using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Windows.Forms;
//
// Author: Barret
//
namespace Infor.SunSystems.V4 {
/// <summary>
/// Print Service
/// </summary>
public class PrintService {
/// <summary>
/// Contruct method to register the print page event
/// </summary>
public PrintService() {
_docToPrint.PrintPage += new PrintPageEventHandler(docToPrint_PrintPage);
}
/// <summary>
/// Show the print dialog and execute print action if necessary
/// </summary>
/// <param name="printType"></param>
/// <param name="font"></param>
private void Print(PrintType printType, Font font) {
_printType = printType;
_printFont = font;
// Allow the user to choose the page range he or she would
// like to print.
PrintDialog printDialog = new PrintDialog();
printDialog.AllowSomePages = true;
printDialog.UseEXDialog = false;
// Show the help button.
printDialog.ShowHelp = true;
// Set the Document property to the PrintDocument for
// which the PrintPage Event has been handled. To display the
// dialog, either this property or the PrinterSettings property
// must be set
printDialog.Document = _docToPrint;
DialogResult result = printDialog.ShowDialog();
// If the result is OK then print the document.
if (result == DialogResult.OK) {
_docToPrint.Print();
}
}
/// <summary>
/// Set properties on the PrintDialog object and then display the dialog.
/// </summary>
/// <param name="printer"></param>
/// <param name="pages"></param>
/// <param name="font"></param>
public void StartPrint(string printer, IList<string> pages, int linesPerPage, Font font) {
_pagesToPrint = pages;
_linesPerPage = linesPerPage;
// Set the default printer
if (!string.IsNullOrEmpty(printer)) {
_docToPrint.PrinterSettings.PrinterName = printer;
}
// Initialize the page range
if (_pagesToPrint.Count > 1) {
_docToPrint.PrinterSettings.MinimumPage = MINMUM_PAGE;
_docToPrint.PrinterSettings.MaximumPage = _pagesToPrint.Count;
_docToPrint.PrinterSettings.FromPage = _docToPrint.PrinterSettings.MinimumPage;
_docToPrint.PrinterSettings.ToPage = _docToPrint.PrinterSettings.MaximumPage;
}
Print(PrintType.TextPages, font);
}
/// <summary>
/// Set properties on the PrintDialog object and then display the dialog.
/// </summary>
/// <param name="pages"></param>
/// <param name="font"></param>
public void StartPrint(IList<string> pages, int linesPerPage, Font font) {
StartPrint(null, pages, linesPerPage, font);
}
/// <summary>
/// Set properties on the PrintDialog object and then display the dialog.
/// </summary>
/// <param name="text"></param>
/// <param name="font"></param>
public void StartPrint(string text, Font font) {
_textToPrint = text;
Print(PrintType.Text, font);
}
/// <summary>
/// Set properties on the PrintDialog object and then display the dialog.
/// </summary>
/// <param name="streamToPrint"></param>
/// <param name="printType"></param>
/// <param name="font"></param>
public void StartPrint(Stream streamToPrint, PrintType printType, Font font) {
_streamToPrint = streamToPrint;
Print(printType, font);
}
/// <summary>
/// Handling the document's PrintPage event. The PrintDialog will print the document by call back this method.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void docToPrint_PrintPage(object sender, PrintPageEventArgs e) {
// Insert code to render the page here.
// This code will be called when the control is drawn.
switch (_printType) {
case PrintType.TextPages:
if (e.PageSettings.PrinterSettings.PrintRange == PrintRange.SomePages && _currentPage == 0) {
_currentPage = e.PageSettings.PrinterSettings.FromPage - 1;
}
ScaleReport(e);
e.Graphics.DrawString(_pagesToPrint[_currentPage], _printFont, Brushes.Black, e.MarginBounds.X,
e.MarginBounds.Y);
_currentPage += 1;
ProcessMorePages(e);
break;
case PrintType.Text:
e.Graphics.DrawString(_textToPrint, _printFont, Brushes.Black, e.MarginBounds.X,
e.MarginBounds.Y);
break;
case PrintType.Image:
Image image = Image.FromStream(_streamToPrint);
int x = e.MarginBounds.X;
int y = e.MarginBounds.Y;
int width = image.Width;
int height = image.Height;
if ((width / e.MarginBounds.Width) > (height / e.MarginBounds.Height)) {
width = e.MarginBounds.Width;
height = image.Height * e.MarginBounds.Width / image.Width;
} else {
height = e.MarginBounds.Height;
width = image.Width * e.MarginBounds.Height / image.Height;
}
Rectangle destRect = new Rectangle(x, y, width, height);
e.Graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel);
break;
default:
break;
}
}
/// <summary>
/// Set property HasMorePages for event argument when there is more page to print
/// </summary>
/// <param name="e"></param>
private void ProcessMorePages(PrintPageEventArgs e) {
bool anyMorePage = (e.PageSettings.PrinterSettings.PrintRange != PrintRange.SomePages &&
_currentPage < _pagesToPrint.Count) ||
(e.PageSettings.PrinterSettings.PrintRange == PrintRange.SomePages &&
_currentPage < e.PageSettings.PrinterSettings.ToPage);
// Set the true for e.HasMorePages when there any more page waiting for print. Otherwise, set false to it.
if (anyMorePage) {
e.HasMorePages = true;
} else {
_currentPage = 0;
e.HasMorePages = false;
}
}
/// <summary>
/// Scale the report to adapt to the width of paper when it is not enough for the whole repot width
/// </summary>
/// <param name="e"></param>
private void ScaleReport(PrintPageEventArgs e) {
float widthScale = GetScale(e, true);
float heightScale = GetScale(e, false);
e.Graphics.ScaleTransform(widthScale, heightScale);
}
private float GetScale(PrintPageEventArgs e, bool isWidth) {
float scale = 1;
int paperValue;
float contentValue;
if (isWidth) {
paperValue = e.MarginBounds.Width;
contentValue = (int)e.Graphics.MeasureString(ONE_LINE_REPORT, _printFont).Width;
} else {
paperValue = e.MarginBounds.Height;
contentValue = (int)e.Graphics.MeasureString(ONE_LINE_REPORT, _printFont).Height * _linesPerPage;
}
// Evaluate the scale
if ((contentValue > paperValue) && (paperValue > 0)) {
scale = paperValue / contentValue;
// Paper value is 'int' and it is not exact. So here to just it advance
if (scale < 1 - 0.046F) {
scale += 0.046F;
}
}
return scale;
}
// Declare the PrintDocument object.
private PrintDocument _docToPrint = new PrintDocument();
private PrintType _printType;
private Font _printFont;
private int _currentPage = 0;
private int _linesPerPage;
private IList<string> _pagesToPrint;
private string _textToPrint;
private Stream _streamToPrint;
private static string ONE_LINE_REPORT = "------------------------------------------------------------------------------------------------------------------------------------";
private static int MINMUM_PAGE = 1;
}
public enum PrintType {
TextPages,
Text,
Image
}
}
No comments:
Post a Comment