using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Drawing; using System.Drawing.Printing; using System.IO; using System.Runtime.Serialization.Formatters.Binary; using System.Security.Cryptography; using Curtain.Log; namespace Dongke.WinForm.Controls.InvoiceLayout { public class InvoiceLayoutPrinter { #region 常量 #region 保存、读取相关 // TODO 加密保存 解密读取 private static byte[] KEY = new byte[] { 106, 240, 243, 74, 29, 163, 145, 29, 39, 65, 118, 96, 247, 237, 40, 121, 116, 10, 14, 50, 139, 117, 244, 163, 193, 190, 184, 66, 8, 185, 78, 73 }; private static byte[] IV = new byte[] { 26, 122, 25, 28, 97, 211, 152, 32, 223, 110, 120, 242, 170, 35, 96, 93 }; //private static ICryptoTransform _decryptor = null; #endregion 保存、读取相关 #endregion #region 成员变量 private PropertyOfLayoutBox Property = null; private GridItem OneGridItem = null; private List LayoutItems = null; private int PageWidthPixel = 0; private int PageHeightPixel = 0; private RectangleF BackImgRectangleF = RectangleF.Empty; private float _allOffsetX = 0; private float _allOffsetY = 0; private int _printPageNum = 1; // 打印页的当前页码 private int _printTotalPageNum = 1; // 总页数 private DataRow _printData = null; private DataTable _printGridData = null; private PrintDocument _printDocument = new PrintDocument(); #endregion #region 构造函数 static InvoiceLayoutPrinter() { //Rijndael age = Rijndael.Create(); //_decryptor = age.CreateDecryptor(KEY, IV); } private InvoiceLayoutPrinter() { _printDocument.DocumentName = "LayoutDocument"; _printDocument.BeginPrint += new PrintEventHandler(this.printDocument_BeginPrint); _printDocument.PrintPage += new PrintPageEventHandler(this.PrintDocument_PrintPage); } #endregion private void printDocument_BeginPrint(object sender, PrintEventArgs e) { } private void PrintDocument_PrintPage(object sender, PrintPageEventArgs e) { try { e.Graphics.PageUnit = GraphicsUnit.Millimeter; e.HasMorePages = DrawPage(e.Graphics); } catch (Exception ex) { Logger.Error(ex); } } public static List Print(byte[] layout, DataRow data, DataTable detail) { if (layout == null || layout.Length == 0) { throw new System.ArgumentNullException("layout"); } if (data == null) { throw new System.ArgumentNullException("data"); } //if (detail == null || detail.Rows.Count == 0) //{ // throw new System.ArgumentNullException("detail"); //} try { InvoiceLayoutPrinter printer = new InvoiceLayoutPrinter(); printer.LayoutItems = new List(); printer.ReadLayout(layout); printer._printData = data; printer._printGridData = detail; //return printer.DrawImages().ToArray(); return printer.DrawImages(); } catch (Exception ex) { throw ex; } } public static void Print(string printerName, short copies, byte[] layout, DataRow data, DataTable detail) { if (layout == null || layout.Length == 0) { throw new System.ArgumentNullException("layout"); } if (data == null) { throw new System.ArgumentNullException("data"); } //if (detail == null || detail.Rows.Count == 0) //{ // throw new System.ArgumentNullException("detail"); //} try { InvoiceLayoutPrinter printer = new InvoiceLayoutPrinter(); printer.LayoutItems = new List(); printer.ReadLayout(layout); printer._printData = data; printer._printGridData = detail; printer._printDocument.PrinterSettings.PrinterName = printerName; printer._printDocument.PrinterSettings.Copies = copies; printer._printDocument.Print(); //return printer.DrawImages().ToArray(); //return printer.DrawImages(); } catch (Exception ex) { throw ex; } } #region 票据打印 private void ReadLayout(byte[] layout) { try { using (MemoryStream stream = new MemoryStream(layout)) { stream.Position = 0; // 反序列化 BinaryFormatter formatter = new BinaryFormatter(); // TODO 解密读取 //if (CryptoStream) if (true) { //using (CryptoStream cStream = new CryptoStream(stream, _decryptor, CryptoStreamMode.Read)) Rijndael age = Rijndael.Create(); using (CryptoStream cStream = new CryptoStream(stream, age.CreateDecryptor(KEY, IV), CryptoStreamMode.Read)) { this.Property = (PropertyOfLayoutBox)formatter.Deserialize(cStream); } } else { this.Property = (PropertyOfLayoutBox)formatter.Deserialize(stream); } //_lastItemRF = propertyOflayoutBox.LastItemRF; //_newItemID = propertyOflayoutBox.NewItemID; //_paperHeight = propertyOflayoutBox.PaperHeight; //_paperWidth = propertyOflayoutBox.PaperWidth; //if (_zoomType != ZoomType.Whole) //{ // ChangePaperSize(); //} //else //{ // InitializeZoom(); //} //paperArea.BackgroundImage = propertyOflayoutBox.BackgroundImage; //_backgroundImageName = propertyOflayoutBox.BackgroundImageName; //_isPrintBackground = propertyOflayoutBox.PrintBackground; //_isPrintAreaVisible = propertyOflayoutBox.PrintAreaVisible; ArrayList items = this.Property.Items; if (items != null && 0 < items.Count) { foreach (LayoutItem item in items) { //item.Init(this, false); //item.Init(); this.LayoutItems.Add(item); if (item.ItemType == ItemType.Grid) { this.OneGridItem = item as GridItem; if (this.OneGridItem.HeadRowsHeight == 0) { this.OneGridItem.HeadRowsHeight = this.OneGridItem.RowsHeight; } } } } //paperArea.Select(); //RefreshItemsBound(); ////paperArea.Refresh(); //return true; } } catch (Exception ex) { throw ex; } } private List DrawImages() { this.PageWidthPixel = LayoutCommon.MillimeterToPixel(this.Property.PaperWidth); this.PageHeightPixel = LayoutCommon.MillimeterToPixel(this.Property.PaperHeight); this._printPageNum = 1; this._printTotalPageNum = 1; //if (this.OneGridItem != null) //{ // foreach (LayoutItem item in this.LayoutItems) // { // if (item.ItemType == ItemType.Grid) // { // GridItem gItem = (item as GridItem); // gItem.PrintGridSource = this._printGridData; // _printTotalPageNum = Math.Max(_printTotalPageNum, gItem.PrintTotalPageNum); // } // } //} List images = new List(); //Bitmap pageImage = null; //Graphics pageGraphics = null; bool hasNextPage = true; while (hasNextPage) { Bitmap pageImage = new Bitmap(this.PageWidthPixel, this.PageHeightPixel); pageImage.SetResolution(LayoutCommon.DPI, LayoutCommon.DPI); using (Graphics pageGraphics = Graphics.FromImage(pageImage)) { // TODO 白色背景 pageGraphics.Clear(Color.White); //pageGraphics.FillRectangle(Brushes.White, pageGraphics.ClipBounds); pageGraphics.PageUnit = GraphicsUnit.Millimeter; hasNextPage = DrawPage(pageGraphics); images.Add(pageImage); } } return images; } private bool DrawPage(Graphics graphics) { //try { // 背景打印 if (this.Property.PrintBackground) { PrintBackgroundImage(graphics); } // Item打印 foreach (LayoutItem layoutItem in this.LayoutItems) { switch (layoutItem.ItemType) { case ItemType.Text: DrawTextItem(graphics, (TextItem)layoutItem); break; case ItemType.Image: DrawImageItem(graphics, (ImageItem)layoutItem); break; case ItemType.Rectangle: DrawRectangleItem(graphics, (RectangleItem)layoutItem); break; case ItemType.Ellipse: DrawEllipseItem(graphics, (EllipseItem)layoutItem); break; //case ItemType.Line: // DrawLineItem(graphics, (LineItem)layoutItem); // break; case ItemType.Grid: DrawGridItem(graphics, (GridItem)layoutItem); break; case ItemType.PageNum: DrawPageNumItem(graphics, (PageNumItem)layoutItem); break; case ItemType.TotalText: DrawTotalTextItem(graphics, (TotalTextItem)layoutItem); break; default: //throw new NotImplementedException(); break; } } // 表格Item是否有下一页 if (_printPageNum < _printTotalPageNum) { _printPageNum++; //e.HasMorePages = true; return true; } return false; } //catch (Exception ex) //{ // throw ex; //} } #region 绘制 /// /// 打印背景图片 /// /// 用于绘制的System.Drawing.Graphics private void PrintBackgroundImage(Graphics graphics) { if (this.Property.BackgroundImage != null) { if (this.BackImgRectangleF.IsEmpty) { // 背景图片的高宽比例 float imgWHRate = (float)this.Property.BackgroundImage.Width / (float)this.Property.BackgroundImage.Height; // 打印纸张的高宽比例 float paperWHRate = this.Property.PaperWidth / this.Property.PaperHeight; // 缩放背景图片,但保持图片高宽比例 if (imgWHRate > paperWHRate) { BackImgRectangleF.Width = this.Property.PaperWidth; BackImgRectangleF.Height = this.Property.PaperWidth / imgWHRate; BackImgRectangleF.X = 0; BackImgRectangleF.Y = (this.Property.PaperHeight - BackImgRectangleF.Height) / 2 + 0; } else { BackImgRectangleF.Width = this.Property.PaperHeight * imgWHRate; BackImgRectangleF.Height = this.Property.PaperHeight; BackImgRectangleF.X = (this.Property.PaperWidth - BackImgRectangleF.Width) / 2 + 0; BackImgRectangleF.Y = 0; } } // 在指定的范围绘制背景图片 graphics.DrawImage(this.Property.BackgroundImage, BackImgRectangleF); } } /// /// 打印文本Item /// /// 用于绘制的System.Drawing.Graphics /// 文本Item private void DrawTextItem(Graphics graphics, TextItem textItem) { // 文本Item打印范围 RectangleF rectangleFM = new RectangleF( _allOffsetX + textItem.Left, _allOffsetY + textItem.Top, textItem.Width, textItem.Height); RectangleF rectangleF = rectangleFM; rectangleF.Inflate(0 - LayoutConsts.TEXT_MARGIN, 0 - LayoutConsts.TEXT_MARGIN); rectangleFM.Height -= LayoutConsts.TEXT_MARGIN; object value = null; if (this._printData.Table.Columns.Contains(textItem.DataMember)) { value = this._printData[textItem.DataMember]; } textItem.PrintTextItem(value, graphics, rectangleFM, rectangleF); } /// /// 打印图片Item /// /// 用于绘制的System.Drawing.Graphics /// 图片Item private void DrawImageItem(Graphics graphics, ImageItem imageItem) { // 图片Item打印范围 RectangleF rectangleF = new RectangleF( _allOffsetX + imageItem.Left, _allOffsetY + imageItem.Top, imageItem.Width, imageItem.Height); // 在指定的范围绘制图片Item LayoutUtility.DrawImage(graphics, rectangleF, imageItem.Image); } /// /// 打印矩形Item /// /// 用于绘制的System.Drawing.Graphics /// 矩形Item private void DrawRectangleItem(Graphics graphics, RectangleItem rectangleItem) { // 矩形Item打印范围 RectangleF rectangleF = new RectangleF( _allOffsetX + rectangleItem.Left, _allOffsetY + rectangleItem.Top, rectangleItem.Width, rectangleItem.Height); float lineWidthDraw = rectangleItem.LineWidth; // 在指定的范围绘制矩形Item LayoutUtility.DrawRectangle(graphics, rectangleF, rectangleItem.LineColor, rectangleItem.FillColor, lineWidthDraw, rectangleItem.Transparent); } /// /// 打印椭圆Item /// /// 用于绘制的System.Drawing.Graphics /// 椭圆Item private void DrawEllipseItem(Graphics graphics, EllipseItem ellipseItem) { // 椭圆Item打印范围 RectangleF rectangleF = new RectangleF( _allOffsetX + ellipseItem.Left, _allOffsetY + ellipseItem.Top, ellipseItem.Width, ellipseItem.Height); float lineWidthDraw = ellipseItem.LineWidth; // 在指定的范围绘制椭圆Item LayoutUtility.DrawEllipse(graphics, rectangleF, ellipseItem.LineColor, ellipseItem.FillColor, lineWidthDraw, ellipseItem.Transparent); } /// /// 打印表格Item /// /// 用于绘制的System.Drawing.Graphics /// 表格Item private void DrawGridItem(Graphics graphics, GridItem gridItem) { // 表格Item打印范围 RectangleF rectangleF = new RectangleF( _allOffsetX + gridItem.Left, _allOffsetY + gridItem.Top, gridItem.Width, gridItem.Height); // 在指定的范围绘制表格Item //gridItem.DrawGridItem(graphics, rectangleF, 1, _printPageNum); gridItem.PrintGridItem(graphics, rectangleF, _printPageNum); } /// /// 打印页码Item /// /// 用于绘制的System.Drawing.Graphics /// 页码Item private void DrawPageNumItem(Graphics graphics, PageNumItem pageNumItem) { // 文本Item打印范围 RectangleF rectangleFM = new RectangleF( _allOffsetX + pageNumItem.Left, _allOffsetY + pageNumItem.Top, pageNumItem.Width, pageNumItem.Height); RectangleF rectangleF = rectangleFM; rectangleF.Inflate(0 - LayoutConsts.TEXT_MARGIN, 0 - LayoutConsts.TEXT_MARGIN); rectangleFM.Height -= LayoutConsts.TEXT_MARGIN; // 在指定的范围绘制文本Item LayoutUtility.DrawText(graphics, rectangleFM, rectangleF, pageNumItem.GetPrintText(this._printPageNum, this._printTotalPageNum), pageNumItem.Font, pageNumItem.TextColor, 0, 0, 0, pageNumItem.TextAlign, pageNumItem.TextAlignVertical, false, false, false); } /// /// 打印合计Item /// /// 用于绘制的System.Drawing.Graphics /// 合计Item private void DrawTotalTextItem(Graphics graphics, TotalTextItem totalTextItem) { // 文本Item打印范围 RectangleF rectangleFM = new RectangleF( _allOffsetX + totalTextItem.Left, _allOffsetY + totalTextItem.Top, totalTextItem.Width, totalTextItem.Height); RectangleF rectangleF = rectangleFM; rectangleF.Inflate(0 - LayoutConsts.TEXT_MARGIN, 0 - LayoutConsts.TEXT_MARGIN); rectangleFM.Height -= LayoutConsts.TEXT_MARGIN; if (_printPageNum != _printTotalPageNum && totalTextItem.NotTotalValue != "[#合计值#]") { LayoutUtility.DrawText(graphics, rectangleFM, rectangleF, totalTextItem.NotTotalValue, totalTextItem.NotTotalFont, totalTextItem.NotTotalColor, totalTextItem.LineSpace, totalTextItem.CharacterSpace, totalTextItem.CharacterCount, totalTextItem.NotTotalAlign, totalTextItem.NotTotalAlignVertical, totalTextItem.Wrap, totalTextItem.Clip, false); return; } // 在指定的范围绘制文本Item object value = null; if (this._printData.Table.Columns.Contains(totalTextItem.DataMember)) { value = this._printData[totalTextItem.DataMember]; } value = totalTextItem.ResetTextValue(value, true); LayoutUtility.DrawText(graphics, rectangleFM, rectangleF, (value == null? "": value.ToString()), totalTextItem.Font, totalTextItem.TextColor, totalTextItem.LineSpace, totalTextItem.CharacterSpace, totalTextItem.CharacterCount, totalTextItem.TextAlign, totalTextItem.NotTotalAlignVertical, totalTextItem.Wrap, totalTextItem.Clip, false); } #endregion #endregion } }