using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO; using System.Drawing.Imaging; using System.Drawing.Printing; namespace ConvertImage { public class PrintDataGridView { #region 变量 /// <summary> /// 打印的datagridview /// </summary> private DataGridView dgvInfo; /// <summary> /// 截取图片数量计数器 /// </summary> private int nCount; /// <summary> /// 打印文档对象 /// </summary> private PrintDocument pdDocument; /// <summary> /// 分割图片集合 /// </summary> private List<Image> lImages; /// <summary> /// 字的高度单元 /// </summary> private int nHeaderHeight; /// <summary> /// 时间信息左侧 /// </summary> private float fTimeLeft; /// <summary> /// 时间信息上放 /// </summary> private float fTimeTop; /// <summary> /// 尾信息左侧 /// </summary> private float fFooterLeft; /// <summary> /// 尾信息上方 /// </summary> private float fFooterTop; /// <summary> /// 打印标题 /// </summary> private string strTitle; /// <summary> /// 标题上方 /// </summary> private float fTitleTop; /// <summary> /// 标题左侧 /// </summary> private float fTitleLeft; /// <summary> /// 是否有标题 /// </summary> private bool hasTitle; #endregion #region 构造函数 /// <summary> /// 带有标题的构造函数 /// </summary> /// <param name="dgvInfo"></param> /// <param name="printTitle"></param> public PrintDataGridView(DataGridView dgvInfo, string strTitle) { this.dgvInfo = dgvInfo; this.nCount = 0; this.pdDocument = new PrintDocument(); this.lImages = new List<Image>(); this.nHeaderHeight = 0; this.fTimeLeft = 0f; this.fTimeTop = 0f; this.fFooterLeft = 0f; this.fFooterTop = 0f; this.strTitle = strTitle; fTitleTop = 0f; fTitleLeft = 0f; if (!string.IsNullOrEmpty(strTitle)) { hasTitle = true; } else { hasTitle = false; } } /// <summary> /// 不带标题的构造函数 /// </summary> /// <param name="dgvInfo"></param> public PrintDataGridView(DataGridView dgvInfo) : this(dgvInfo, string.Empty) { } #endregion #region 方法 /// <summary> /// 生成datagridview图片 /// </summary> /// <param name="view"></param> /// <returns></returns> private static Bitmap GetDataGridView(DataGridView dgvInfo) { // 将datagridview的自动扩展打开 dgvInfo.AutoSize = true; // 建立datagridview图片 Bitmap bmNewBitmap = new Bitmap(dgvInfo.Width - 32, dgvInfo.Height - 32); dgvInfo.DrawToBitmap(bmNewBitmap, new Rectangle(0, 0, dgvInfo.Width, dgvInfo.Height)); // 将datagridview恢复原状 dgvInfo.AutoSize = false; return bmNewBitmap; } /// <summary> /// 设置页面头 /// </summary> /// <param name="e"></param> /// <param name="printTime"></param> private void setHeader(System.Drawing.Printing.PrintPageEventArgs e, string strTitle, string strTime, bool hasTitle) { // 打印时间 strTime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"); // 字高度单元 nHeaderHeight = (int)Math.Ceiling(Convert.ToDouble(e.Graphics.MeasureString(strTime, new Font(dgvInfo.Font, FontStyle.Bold)).Height)); // 含有标题 if (hasTitle) { fTitleLeft = e.MarginBounds.Left + (e.MarginBounds.Width - e.Graphics.MeasureString(strTitle, new Font(dgvInfo.Font, FontStyle.Bold)).Width) / 2; fTitleTop = e.MarginBounds.Top; fTimeTop = e.MarginBounds.Top + nHeaderHeight; } // 没有标题 else { fTimeTop = e.MarginBounds.Top; } fTimeLeft = e.MarginBounds.Left + e.MarginBounds.Width - e.Graphics.MeasureString(strTime, new Font(dgvInfo.Font, FontStyle.Bold)).Width; } /// <summary> /// 设置页面尾 /// </summary> /// <param name="e"></param> /// <param name="pageNum"></param> private void setFooter(System.Drawing.Printing.PrintPageEventArgs e, string strPageNum) { fFooterLeft = e.MarginBounds.Left + (e.MarginBounds.Width - e.Graphics.MeasureString(strPageNum, new Font(dgvInfo.Font, FontStyle.Bold)).Width) / 2; fFooterTop = e.MarginBounds.Top + e.MarginBounds.Height - nHeaderHeight; } /// <summary> /// 设置打印图片 /// </summary> /// <param name="e"></param> private void setImageForPrint(System.Drawing.Printing.PrintPageEventArgs e) { // 得到原始图片 Bitmap bmImage = GetDataGridView(dgvInfo); // 纸张宽 float fPageWidth = e.MarginBounds.Width; // 纸张高 float fPageHeight; if (hasTitle) { fPageHeight = e.MarginBounds.Height - nHeaderHeight * 3; } else { fPageHeight = e.MarginBounds.Height - nHeaderHeight * 2; } // 得到所有分页图片 lImages = getAllImages(bmImage, fPageWidth, fPageHeight); } /// <summary> /// 分割图片 /// </summary> /// <param name="sourceImage"></param> /// <param name="pageWidth"></param> /// <param name="pageHeigh"></param> /// <returns></returns> private List<Image> getAllImages(Bitmap bmSourceImage, float fPageWidth, float fPageHeigh) { List<Image> lImages = new List<Image>(); // 距离图片左边位置 float fLeft = 0; // 距离图片上边位置 float fTop = 0; // 切割部分 RectangleF rfPart; // 切割图像 Bitmap bmPartImage; // 下方还有图片 while ((fTop + fPageHeigh) < bmSourceImage.Height) { // 右侧还有图片 while ((fLeft + fPageWidth) < bmSourceImage.Width) { rfPart = new RectangleF(fLeft, fTop, fPageWidth, fPageHeigh); bmPartImage = bmSourceImage.Clone(rfPart, PixelFormat.DontCare); lImages.Add(bmPartImage); fLeft += fPageWidth; } // 最右边一个图片 rfPart = new RectangleF(fLeft, fTop, bmSourceImage.Width - fLeft, fPageHeigh); bmPartImage = bmSourceImage.Clone(rfPart, PixelFormat.DontCare); lImages.Add(bmPartImage); fTop += fPageHeigh; fLeft = 0; } // 最下方的图片 while ((fLeft + fPageWidth) < bmSourceImage.Width) { rfPart = new RectangleF(fLeft, fTop, fPageWidth, bmSourceImage.Height - fTop); bmPartImage = bmSourceImage.Clone(rfPart, PixelFormat.DontCare); lImages.Add(bmPartImage); fLeft += fPageWidth; } // 右下角的图片 rfPart = new RectangleF(fLeft, fTop, bmSourceImage.Width - fLeft, bmSourceImage.Height - fTop); bmPartImage = bmSourceImage.Clone(rfPart, PixelFormat.DontCare); lImages.Add(bmPartImage); return lImages; } /// <summary> /// 打印分页 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void PrintDoc_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) { string strTime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"); if (nCount == 0) { setHeader(e, strTitle, strTime, hasTitle); setImageForPrint(e); } if (nCount < lImages.Count) { // Header if (hasTitle) { e.Graphics.DrawString(strTitle, new Font(dgvInfo.Font, FontStyle.Bold), Brushes.Black, fTitleLeft, fTitleTop); } e.Graphics.DrawString(strTime, new Font(dgvInfo.Font, FontStyle.Bold), Brushes.Black, fTimeLeft, fTimeTop); // 预览图片生成 if (hasTitle) { e.Graphics.DrawImage(lImages.ElementAt(nCount), new Rectangle(e.MarginBounds.Left, e.MarginBounds.Top + nHeaderHeight * 2, lImages.ElementAt(nCount).Width, lImages.ElementAt(nCount).Height)); } else { e.Graphics.DrawImage(lImages.ElementAt(nCount), new Rectangle(e.MarginBounds.Left, e.MarginBounds.Top + nHeaderHeight, lImages.ElementAt(nCount).Width, lImages.ElementAt(nCount).Height)); } string strPageNum = (nCount + 1) + "/" + lImages.Count; setFooter(e, strPageNum); // Footer e.Graphics.DrawString(strPageNum, new Font(dgvInfo.Font, FontStyle.Bold), Brushes.Black, fFooterLeft, fFooterTop); nCount++; if (nCount < lImages.Count) { e.HasMorePages = true; } else { e.HasMorePages = false; nCount = 0; } } } /// <summary> /// 打印一页 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void PrintDoc_PrintPageInOne(object sender, System.Drawing.Printing.PrintPageEventArgs e) { string strTime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"); setHeader(e, strTitle, strTime, hasTitle); // Header if (hasTitle) { e.Graphics.DrawString(strTitle, new Font(dgvInfo.Font, FontStyle.Bold), Brushes.Black, fTitleLeft, fTitleTop); } e.Graphics.DrawString(strTime, new Font(dgvInfo.Font, FontStyle.Bold), Brushes.Black, fTimeLeft, fTimeTop); // 预览图片生成 if (hasTitle) { e.Graphics.DrawImage(GetDataGridView(dgvInfo), new Rectangle(e.MarginBounds.Left, e.MarginBounds.Top + nHeaderHeight * 2, e.MarginBounds.Width, e.MarginBounds.Height - nHeaderHeight * 3), new Rectangle(0, 0, GetDataGridView(dgvInfo).Width, GetDataGridView(dgvInfo).Height), GraphicsUnit.Pixel); } else { e.Graphics.DrawImage(GetDataGridView(dgvInfo), new Rectangle(e.MarginBounds.Left, e.MarginBounds.Top + nHeaderHeight, e.MarginBounds.Width, e.MarginBounds.Height - nHeaderHeight * 2), new Rectangle(0, 0, GetDataGridView(dgvInfo).Width, GetDataGridView(dgvInfo).Height), GraphicsUnit.Pixel); } string strPageNum = 1 + "/" + 1; setFooter(e, strPageNum); // Footer e.Graphics.DrawString(strPageNum, new Font(dgvInfo.Font, FontStyle.Bold), Brushes.Black, fFooterLeft, fFooterTop); } /// <summary> /// 打印多页 /// </summary> public void Print() { pdDocument.PrintPage += new PrintPageEventHandler(PrintDoc_PrintPage); PageSetupDialog setup = new PageSetupDialog(); setup.Document = pdDocument; setup.PageSettings.PaperSize = pdDocument.DefaultPageSettings.PaperSize; DialogResult result = setup.ShowDialog(); if (result == DialogResult.OK) { PrintPreviewDialog dlgPrintPreview = new PrintPreviewDialog(); dlgPrintPreview.Document = pdDocument; dlgPrintPreview.ShowIcon = false; dlgPrintPreview.ShowDialog(); } } /// <summary> /// 打印一页 /// </summary> public void PrintInOne() { pdDocument.PrintPage += new PrintPageEventHandler(PrintDoc_PrintPageInOne); PageSetupDialog setup = new PageSetupDialog(); setup.Document = pdDocument; setup.PageSettings.PaperSize = pdDocument.DefaultPageSettings.PaperSize; DialogResult result = setup.ShowDialog(); if (result == DialogResult.OK) { PrintPreviewDialog dlgPrintPreview = new PrintPreviewDialog(); dlgPrintPreview.Document = pdDocument; dlgPrintPreview.ShowIcon = false; dlgPrintPreview.ShowDialog(); } } #endregion } }