c#自定义报表打印(非reportviewer)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Reporting.WinForms;

using System.IO;
using System.Drawing.Imaging;
using System.Drawing.Printing;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private List<Stream> m_streams;
        private int m_currentPageIndex;//用来记录当前打印到第几页了


        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //控件绑定报表
            reportViewer1.LocalReport.ReportPath = @"F:\test\QueueTest\WindowsFormsApplication1\Report1.rdlc";
            //报表绑定数据集
            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("DTTEST", GetTable()));
            this.reportViewer1.RefreshReport();
        }

        private DataTable GetTable()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("C1", typeof(string));//列名必须与数据集的列名一致
            dt.Columns.Add("C2", typeof(string));//列名必须与数据集的列名一致
            dt.Columns.Add("C3", typeof(string));//列名必须与数据集的列名一致
            //动态图片绑定 
            string c = Convert.ToBase64String(ImageToBytes("F:\\wenbin\\工作文件\\SF\\LOGO\\顺丰logo简体.jpg"));
            dt.Rows.Add(c, "陈先生收", "深圳市");
            return dt;
        }

        /// <summary>
        /// 将图片转成byte[]
        /// </summary>
        /// <param name="path">图片路径</param>
        /// <returns></returns>
        private byte[] ImageToBytes(string path)
        {
            Image image = Image.FromFile(path);
            //ImageFormat format = image.RawFormat;
            using (MemoryStream ms = new MemoryStream())
            {
                image.Save(ms, image.RawFormat);
                byte[] buffer = new byte[ms.Length];
                //ms.Position = 0;//ms.Seek(0, SeekOrigin.Begin);
                //ms.Read(buffer, 0, buffer.Length);
                buffer = ms.ToArray();
                return buffer;
            }
        }

        /// <summary>
        /// 将byte[]转成图片
        /// </summary>
        /// <param name="buffer">byte[]</param>
        /// <returns></returns>
        private Image BytesToImage(byte[] buffer)
        {
            MemoryStream ms = new MemoryStream(buffer);
            Image image = Image.FromStream(ms);
            return image;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Run();
        }

        private void Export(LocalReport report)
        {
            //EMF
            string deviceInfo = "<DeviceInfo>" +

                                       "  <OutputFormat>PNG</OutputFormat>" +

                                       "  <PageWidth>8.5in</PageWidth>" +

                                       "  <PageHeight>11in</PageHeight>" +

                                       "  <MarginTop>0in</MarginTop>" +

                                       "  <MarginLeft>0in</MarginLeft>" +

                                       "  <MarginRight>0in</MarginRight>" +

                                       "  <MarginBottom>0in</MarginBottom>" +

                                       "</DeviceInfo>";
            Warning[] warnings;
            m_streams = new List<Stream>();
            //将报表的内容按照deviceInfo指定的格式输出到CreateStream函数提供的Stream中。
            report.Render("Image", deviceInfo, CreateStream, out warnings);
            foreach (Stream stream in m_streams)
            {
                stream.Position = 0;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="name">流的名称</param>
        /// <param name="fileNameExtension">创建文件流时要使用的文件扩展名</param>
        /// <param name="encoding">指定流的字符编码的 Encoding 枚举器值</param>
        /// <param name="mimeType">一个包含流的 MIME 类型的 string</param>
        /// <param name="willSeek">指示流是否需要支持查找的 Boolean 值。如果值为 false,则流将为只前推,并将按其创建顺序发送到块区中的客户端。如果值为 true,则流可以任何顺序写入</param>
        /// <returns></returns>
        private Stream CreateStream(string name, string fileNameExtension, Encoding encoding, string mimeType, bool willSeek)
        {
            Stream stream = new MemoryStream();
            m_streams.Add(stream);
            return stream;
        }

        private void Print()
        {
            if (m_streams == null || m_streams.Count == 0)
            {
                return;
            }
            PrintDocument pd = new PrintDocument();
            pd.DocumentName = "报表测试打印";
            pd.PrintPage += new PrintPageEventHandler(this.Print_Page);//打印内容
            PrintPreviewDialog ppd = new PrintPreviewDialog();
            ppd.Document = pd;
            ppd.ShowDialog();
            //pd.Print();
        }

        private void Run()
        {
            LocalReport report = new LocalReport();
            //设置需要打印的报表的文件名称。
            report.ReportPath = @"F:\test\QueueTest\WindowsFormsApplication1\Report1.rdlc";
            //创建要打印的数据源
            ReportDataSource source = new ReportDataSource("DTTEST", GetTable());
            report.DataSources.Clear();
            report.DataSources.Add(source);
            //刷新报表中的需要呈现的数据
            report.Refresh();
            Export(report);
            m_currentPageIndex = 0;
            Print();
        }

        private void Print_Page(object sender, PrintPageEventArgs e)
        {
            e.Graphics.PageUnit = GraphicsUnit.Millimeter;//毫米单位
            //Metafile pageImage = new Metafile(m_streams[m_currentPageIndex]);
            Image pageImage = Image.FromStream(m_streams[m_currentPageIndex]);
            //e.PageSettings.Landscape = false;//指定是否横向打印
            e.Graphics.DrawImage(pageImage, 0, 0);//这里的Graphics对象实际指向了打印机
            m_streams[m_currentPageIndex].Close();
            m_currentPageIndex++;
            e.HasMorePages = (m_currentPageIndex < m_streams.Count);
        }

    }
}

 

posted @ 2017-01-16 17:21  花生打代码会头痛  阅读(816)  评论(0)    收藏  举报