winform使用PrintDocument控件打印

代码,需要加入的控件:PrintDocument、PageSetupDialog、PrintDialog、PrintPreviewDialog、BackgroundWorker,控件的Document属性要指定为PrintDocument控件的id。
导入Excel用的是12.0的驱动,需要下载:http://download.microsoft.com/download/7/0/3/703ffbcb-dc0c-4e19-b0da-1463960fdcdb/AccessDatabaseEngine.exe 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.OleDb;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace PrintLabels
{
    public partial class MainForm : Form
    {
        /// <summary>
        /// 消息队列
        /// Queue.Peek();//第一个元素; Queue.Dequeue();//移除第一个元素;Queue.Enqueue//添加到 Queue<T> 的末尾
        /// </summary>
        static Queue<Message> queuePrint = new Queue<Message>();
        StringBuilder printResult = new StringBuilder();//打印结果
        //int PrintCount = 0;//打印的标签总数
        string row1;
        string row2;
        string row3;
        string row4;
        string row5;
        string row6;

        public MainForm()
        {
            InitializeComponent();
            this.printDocument1.OriginAtMargins = true;//启用页边距
            this.pageSetupDialog1.EnableMetric = true; //以毫米为单位
            dataGridView1.AutoGenerateColumns = false;//禁止自动创建列
        }
        /// <summary>
        /// 导入excel表格
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnImportExcel_Click(object sender, EventArgs e)
        {
            OpenFileDialog fd = new OpenFileDialog();
            fd.Filter = "Excel(2007)文件|*.xlsx|Excel(97-2003)文件|*.xls|所有文件|*.*";
            fd.Title = "打开文件夹";
            string path = "";
            //fd.InitialDirectory = "d:\\";
            fd.FilterIndex = 1;
            if (fd.ShowDialog() == DialogResult.OK)
            {
                path = fd.FileName;
            }
            if (!string.IsNullOrEmpty(path))
            {
                printResult.Remove(0, printResult.Length);//清除打印结果
                DataSet ds = GetExcelTables(path);//读取Excel到DataSet
                DataTable dtTotal = ds.Tables["总表$"];
                List<TotalModel> totalList = GetTotalData(dtTotal);
                List<PurchaseModel> purchaseList = new List<PurchaseModel>();//打印数据
                foreach (DataTable dt in ds.Tables)
                {
                    if (!dt.TableName.Contains("总表"))
                    {
                        List<PurchaseModel> list = GetPurchaseData(dt, totalList);
                        if (list.Count > 0)
                        {
                            purchaseList.AddRange(list);
                        }
                    }
                }
                string strmsg = printResult.ToString();
                if (strmsg != "")
                {
                    MessageBox.Show(strmsg);
                }
                else
                {
                    dataGridView1.DataSource = purchaseList;
                }
            }
        }

        /// <summary>
        /// 打印设置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSetPrint_Click(object sender, EventArgs e)
        {
            this.pageSetupDialog1.ShowDialog();
        }
        //打印预览
        private void btnPrePrint_Click(object sender, EventArgs e)
        {
            this.printPreviewDialog1.ShowDialog();
        }
        //打印DataGridView数据
        private void btnPrint_Click(object sender, EventArgs e)
        {
            if (this.printDialog1.ShowDialog() == DialogResult.OK)
            {
                if (dataGridView1.Rows[0].Cells[0].Value != null)
                {
                    btnPrint.Enabled = false;

                    //加入队列
                    queuePrint.Clear();
                    List<Message> messages = new List<Message>();
                    foreach (DataGridViewRow dr in dataGridView1.Rows)
                    {
                        if (dr.Cells["DocNo"].Value != null)
                        {
                            string docNo = dr.Cells["DocNo"].Value.ToString();
                            string destination = dr.Cells["Destination"].Value.ToString();
                            string warehouse = dr.Cells["Warehouse"].Value.ToString();
                            string proId = dr.Cells["ProId"].Value.ToString().TrimEnd(',').TrimEnd('');
                            string proName = dr.Cells["ProName"].Value.ToString().TrimEnd(',').TrimEnd('');
                            int boxNum = Convert.ToInt32(dr.Cells["BoxNum"].Value);

                            for (int i = 1; i <= boxNum; i++)
                            {
                                messages.Add(new Message()
                                {
                                    Count = 1,
                                    PM = new PurchaseModel()
                                    {
                                        BoxNum = boxNum,
                                        CurBoxNum = i,
                                        Destination = destination,
                                        DocNo = docNo,
                                        ProId = proId,
                                        ProName = proName,
                                        Warehouse = warehouse
                                    }
                                });
                            }
                        }
                    }
                    Print(messages);//打印
                    btnPrint.Enabled = true;
                }
                else
                {
                    //MessageBox.Show("不允许打印空数据");
                    return;
                }
            }
        }
        /// <summary>
        /// 直接打印
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnPrint2_Click(object sender, EventArgs e)
        {
            if (this.printDialog1.ShowDialog() == DialogResult.OK)
            {
                if (dataGridView1.Rows[0].Cells[0].Value != null)
                {
                    btnPrint.Enabled = false;

                    //加入队列
                    queuePrint.Clear();
                    List<Message> messages = new List<Message>();
                    foreach (DataGridViewRow dr in dataGridView1.Rows)
                    {
                        if (dr.Cells["DocNo"].Value != null)
                        {
                            string docNo = dr.Cells["DocNo"].Value.ToString();
                            string destination = dr.Cells["Destination"].Value.ToString();
                            string warehouse = dr.Cells["Warehouse"].Value.ToString();
                            string proId = dr.Cells["ProId"].Value.ToString().TrimEnd(',').TrimEnd('');
                            string proName = dr.Cells["ProName"].Value.ToString().TrimEnd(',').TrimEnd('');
                            int boxNum = Convert.ToInt32(dr.Cells["BoxNum"].Value);

                            for (int i = 1; i <= boxNum; i++)
                            {
                                messages.Add(new Message()
                                {
                                    Count = 1,
                                    PM = new PurchaseModel()
                                    {
                                        BoxNum = boxNum,
                                        CurBoxNum = i,
                                        Destination = destination,
                                        DocNo = docNo,
                                        ProId = proId,
                                        ProName = proName,
                                        Warehouse = warehouse
                                    }
                                });
                            }
                        }
                    }
                    //Print(messages);

                    queuePrint.AddRange(messages);
                    this.printDocument1.Print();

                    btnPrint.Enabled = true;
                }
                else
                {
                    return;
                }
            }
        }

        #region
        /// <summary>
        /// 把导入的DataTable数据转化为List
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="totalList"></param>
        /// <returns></returns>
        public List<PurchaseModel> GetPurchaseData(DataTable dt, List<TotalModel> totalList)
        {
            string dest = dt.TableName.Replace("$", "");
            List<PurchaseModel> list = new List<PurchaseModel>();

            for (int i = 0; i < dt.Rows.Count; i++)
            {
                DataRow dr = dt.Rows[i];
                if (dr[0].ToString().Contains("采购单号"))
                {
                    string docNo = dr[1].ToString();
                    PurchaseModel purchase = new PurchaseModel();
                    purchase.Destination = dest;
                    purchase.DocNo = docNo;
                    i += 5;
                    for (; i < dt.Rows.Count; i++)
                    {
                        bool isok = false;
                        string proName = "";
                        string proIdStr = "";
                        string warehouse = "";
                        int boxNum = 0;
                        for (; i < dt.Rows.Count; i++)
                        {
                            string proId = dt.Rows[i][0].ToString();//商品编号
                            if (!string.IsNullOrEmpty(proId))
                            {
                                proIdStr += proId + "";
                                proName += dt.Rows[i][1].ToString() + "";//商品名称
                                warehouse = dt.Rows[i][3].ToString();//仓库

                                int purNum = Convert.ToInt32(dt.Rows[i][4].ToString());//采购数量,计算箱数
                                TotalModel totalModel = totalList.Where(c => c.ProNo == proId).First();
                                if (totalModel == null)
                                {
                                    string msg = "表:" + dt.TableName + "  行:" + (i + 1) + "  列:1;无法找到对应总表数据,请检查数据格式!\r\n";
                                    printResult.Append(msg);
                                }
                                else
                                {
                                    int packageNum = totalModel.PackageNum;//箱规
                                    boxNum += ((purNum / packageNum) + ((purNum % packageNum) > 0 ? 1 : 0));//计算出箱数
                                }
                            }
                            else
                            {
                                isok = true;
                                break;
                            }
                        }
                        purchase.BoxNum = boxNum;
                        purchase.ProId = proIdStr.TrimEnd(',');
                        purchase.ProName = proName.TrimEnd(',');
                        purchase.Warehouse = warehouse;

                        if (isok)
                        {
                            break;
                        }
                    }
                    list.Add(purchase);
                }
            }
            return list;
        }
        /// <summary>
        /// 获取总表中箱规数据
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public List<TotalModel> GetTotalData(DataTable dt)
        {
            List<TotalModel> list = new List<TotalModel>();
            for (int i = 2; i < dt.Rows.Count; i++)
            {
                DataRow dr = dt.Rows[i];
                string proNo = dr[0].ToString();
                if (!proNo.Contains("合计"))
                {
                    string pn = dr[dt.Columns.Count - 2].ToString();
                    if (pn != "")
                    {
                        int packageNum = Convert.ToInt32(pn);
                        list.Add(new TotalModel() { ProNo = proNo, PackageNum = packageNum });
                    }
                }
            }
            return list;
        }
        /// <summary>
        /// 获取Excel数据
        /// </summary>
        /// <param name="fullPath"></param>
        /// <returns></returns>
        public DataSet GetExcelTables(string fullPath)
        {
            DataSet ds = new DataSet();
            if (File.Exists(fullPath))
            {
                //HDR=No 第一行就是数据
                string strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fullPath + ";Extended Properties='Excel 12.0;HDR=No;IMEX=1;'";
                using (OleDbConnection conn = new OleDbConnection(strConn))
                {
                    conn.Open();
                    foreach (DataRow item in conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null).Rows)
                    {
                        string tableName = item[2].ToString().Trim();
                        DataTable dt = new DataTable();
                        dt.TableName = tableName;
                        OleDbDataAdapter odda = new OleDbDataAdapter("select * from [" + tableName + "]", conn);
                        odda.Fill(dt);
                        ds.Tables.Add(dt);
                    }
                }
            }
            return ds;
        }
        #endregion

        #region 打印
        internal void Print(Message msg)
        {
            Print(new List<Message>() { msg });
        }
        internal void Print(IList<Message> list)
        {
            if (list == null || list.Count < 1) return;
            queuePrint.AddRange(list);
            if (backgroundWorker1.IsBusy == false)
            {
                backgroundWorker1.RunWorkerAsync();
            }
        }

        bool IsPrinting = false;
        private void DoPrint()
        {
            if (IsPrinting) return;
            while (queuePrint.Count > 0)
            {
                printDocument1.Print();
                //重要,循环作业,UI可接收消息
                Application.DoEvents();//此处解决过多打印队列会使界面假死问题
            }
            IsPrinting = false;
        }
        private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            var worker = sender as BackgroundWorker;
            while (queuePrint.Count > 0)
            {
                if ((worker.CancellationPending == true))
                {
                    e.Cancel = true;
                    break;
                }
                else
                {
                    printDocument1.Print();
                    System.Threading.Thread.Sleep(3000);
                }
            }
        }
        /// <summary>
        /// 填充打印主体
        /// </summary>
        private void fillPrintBody(PurchaseModel lp)
        {
            if (lp == null) return;
            row1 = "供应商名称:xxxxxx";
            row2 = "采购单号:" + lp.DocNo;
            row3 = "目的城市:" + lp.Destination;
            row4 = "仓库:" + lp.Warehouse;
            row5 = "商品名称:" + lp.ProId;
            row6 = "箱数:第" + lp.CurBoxNum + "箱,共" + lp.BoxNum + "";
        }
        private void printDocument1_QueryPageSettings(object sender, System.Drawing.Printing.QueryPageSettingsEventArgs e) { }
        /// <summary>
        /// 打印前
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void printDocument1_BeginPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
        {
            if (queuePrint.Count < 1)
            {
                e.Cancel = true;
                return;
            }
            //printDialog1.PrinterSettings.Copies = 1;// (short)msg.Count; //设置每个只打印一份
            var msg = queuePrint.Peek();
            fillPrintBody(msg.PM);
        }
        /// <summary>
        /// 打印后
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void printDocument1_EndPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
        {
            queuePrint.Dequeue();//移除已被打印的数据
        }
        /// <summary>
        /// 打印文档
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
            //像素偏移方式,像素在水平和垂直距离上均偏移若干个单位,以进行高速锯齿消除。
            e.Graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
            //也可以通过设置Graphics对不平平滑处理方式解决,代码如下: 
            e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

            Font drawFont = new Font("宋体", 10);
            Brush drawBrush = Brushes.Black;
            e.Graphics.DrawString(row1, drawFont, drawBrush, 0, 0);
            e.Graphics.DrawString(row2, drawFont, drawBrush, 0, 20);
            e.Graphics.DrawString(row3, drawFont, drawBrush, 0, 40);
            e.Graphics.DrawString(row4, drawFont, drawBrush, 0, 60);
            e.Graphics.DrawString(row5, drawFont, drawBrush, 0, 80);
            e.Graphics.DrawString(row6, drawFont, drawBrush, 0, 100);

            //float pageW = 79f;
            //float pageH = 50f;
            //var docMargins = this.printDocument1.DefaultPageSettings.Margins;
            //float recW = pageW - docMargins.Left - docMargins.Right;
            //float recH = pageH - docMargins.Top - docMargins.Bottom;
            //var rec1 = new RectangleF(0f, 0f, recW, recH);
            //var rec2 = new RectangleF(0f, 0f, recW, recH);
            //var rec3 = new RectangleF(0f, 0f, recW, recH);
            //var rec4 = new RectangleF(0f, 0f, recW, recH);
            //var rec5 = new RectangleF(0f, 0f, recW, recH);
            //var rec6 = new RectangleF(0f, 0f, recW, recH);

            //e.Graphics.DrawString(row1, drawFont, drawBrush, rec1, sf);
            //e.Graphics.DrawString(row2, drawFont, drawBrush, rec2, sf);

            //queuePrint.Dequeue();
            //if (queuePrint.Count > 0)
            //{
            //    e.HasMorePages = true;
            //}
            //else
            //{
            //    e.HasMorePages = false;
            //}
        }
        #endregion

    }

    public class TotalModel
    {
        /// <summary>
        /// 商品编号
        /// </summary>
        public string ProNo { get; set; }
        /// <summary>
        /// 箱规
        /// </summary>
        public int PackageNum { get; set; }
    }
    public class PurchaseModel
    {
        public string DocNo { get; set; }
        public string Destination { get; set; }
        public string Warehouse { get; set; }
        public string ProName { get; set; }
        public int BoxNum { get; set; }
        public int CurBoxNum { get; set; }
        public string ProId { get; set; }
    }
    internal class Message
    {
        public int Count;
        public PurchaseModel PM { get; set; }
    }
    /// <summary>
    /// 队列
    /// </summary>
    /// <typeparam name="T"></typeparam>
    internal class Queue<T> : List<T>
    {
        /// <summary>
        /// 取出第一个元素
        /// </summary>
        /// <returns></returns>
        public T Peek()
        {
            return this.FirstOrDefault();
        }
        /// <summary>
        /// 删除第一个元素
        /// </summary>
        /// <returns></returns>
        public T Dequeue()
        {
            var item = this.FirstOrDefault();
            if (item != null)
            {
                Remove(item);
            }
            return item;
        }
        /// <summary>
        /// 添加到末尾
        /// </summary>
        /// <param name="item"></param>
        public void Enqueue(T item)
        {
            Add(item);
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/xsj1989/p/10219198.html