| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557 |
-
- 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<LayoutItem> 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<Image> 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<LayoutItem>();
- 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<LayoutItem>();
- 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<Image> 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<Image> images = new List<Image>();
- //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 绘制
- /// <summary>
- /// 打印背景图片
- /// </summary>
- /// <param name="graphics">用于绘制的System.Drawing.Graphics</param>
- 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);
- }
- }
- /// <summary>
- /// 打印文本Item
- /// </summary>
- /// <param name="graphics">用于绘制的System.Drawing.Graphics</param>
- /// <param name="textItem">文本Item</param>
- 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);
- }
- /// <summary>
- /// 打印图片Item
- /// </summary>
- /// <param name="graphics">用于绘制的System.Drawing.Graphics</param>
- /// <param name="imageItem">图片Item</param>
- 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);
- }
- /// <summary>
- /// 打印矩形Item
- /// </summary>
- /// <param name="graphics">用于绘制的System.Drawing.Graphics</param>
- /// <param name="rectangleItem">矩形Item</param>
- 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);
- }
- /// <summary>
- /// 打印椭圆Item
- /// </summary>
- /// <param name="graphics">用于绘制的System.Drawing.Graphics</param>
- /// <param name="ellipseItem">椭圆Item</param>
- 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);
- }
- /// <summary>
- /// 打印表格Item
- /// </summary>
- /// <param name="graphics">用于绘制的System.Drawing.Graphics</param>
- /// <param name="gridItem">表格Item</param>
- 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);
- }
- /// <summary>
- /// 打印页码Item
- /// </summary>
- /// <param name="graphics">用于绘制的System.Drawing.Graphics</param>
- /// <param name="pageNumItem">页码Item</param>
- 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);
- }
- /// <summary>
- /// 打印合计Item
- /// </summary>
- /// <param name="graphics">用于绘制的System.Drawing.Graphics</param>
- /// <param name="totalTextItem">合计Item</param>
- 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
- }
- }
|