C# 使用PdfiumViewer实现对PDF文档打印预览(二)

前言

想要对PDF文档进行预览和打印,实际上这个文档可以是存在的,也可以是一个PDF文件流(本地并没有PDF文件),找了一段时间发现有个特牛逼的开源组件PdfiumViewer,满足我这一切的需求,还可以自定义缩放,翻页的按钮。
但是这个组件需要和pdfium.dll配合使用,放在同一个路径下,运行在X86平台下。

关于PdfiumViewer

GitHub链接:https://github.com/pvginkel/PdfiumViewer

PdfiumViewer 是一个基于PDFium项目的PDF查看器,它提供了许多用于处理PDF文件的组件。承载了一个PdfRenderer控件,并添加一个工具栏老保存或打印PDF文件。
PdfDocument 用于呈现PDF文档的基类
PdfRenderer 是一个winform控件,可以渲染PdfDocument

PdfiumViewer需要PDFium库的支持,在Nuget包中是没有包含这个PDFium库的, 需要自己下载。界面大致是长这个样子,有保存、打印、放大、缩小菜单。
在这里插入图片描述

配置PdfiumViewer环境

使用VS自带的Nuget包管理器下载安装,这里我选择的是第一个。
在这里插入图片描述
然后再下载PDFium.dll,使用Nuget包管理器搜索并下载安装,这里x86_V64.v8-xfa的安装包。
在这里插入图片描述
在工程的 packages\PdfiumViewer.Native.x86.v8-xfa.2018.4.8.256\Build\x86路径下可以看到pdfium.dll, 就把pdfium.dllPdfiumViewer放在同一个路径下就可以使用了。
在这里插入图片描述

PdfiumViewer 打开并预览本地的PDF文档

创建一个winform工程,直接在.cs文件中添加PdfiumViewer即可。也可以直接把PdfiumViewer控件拖拽到工具栏,从工具栏添加这个组件,再编程。
方式1:直接打开已经存在本地的PDF文件。PdfDocument.Load的函数有四个重载,这是其中一个。

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 PdfiumViewer;

namespace PdfiumViewerDemo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            // 加载PDF文档
            LoadPdfByDocument();
        }


       /// <summary>
       /// 加载本地PDF文档
       /// </summary>
        private void LoadPdfByDocument()
        {

            //创建一个PDFView控件
            PdfViewer pdfViewer1 = new PdfViewer();
            //设置位置和大小
            pdfViewer1.Location = new Point(5, 5);
            pdfViewer1.Size = new Size(200, 300);
            pdfViewer1.Dock = DockStyle.Fill;

            //将控件添加到界面上
            this.Controls.Add(pdfViewer1);

            //加载PDF文档
            pdfViewer1.Document = PdfDocument.Load(@"D:Demo.pdf");
        }
    }
}

运行代码的时候如果出现找不到“pdfium.dll”的异常,那么就是pdfium.dll没有和PdfViewer.dll放在同一目录下。
在这里插入图片描述
如果出现System.BadImageFormatException
HResult=0x8007000B
Message=试图加载格式不正确的程序。 (异常来自 HRESULT:0x8007000B)
Source=PdfiumViewer的异常,
在这里插入图片描述
那么很可能就是运行环境不对,应该更改为X86的运行环境。
在这里插入图片描述

运行效果:
在这里插入图片描述

PdfiumViewer 预览PDF文件流

PdfSharpHelper类具体代码如下,更多详细的介绍请移步c# 数据保存为PDF(三) (PdfSharp篇)
https://blog.csdn.net/weixin_40314351/article/details/127343819?spm=1001.2014.3001.5501


using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;

using PdfSharp;
using PdfSharp.Drawing;
using PdfSharp.Pdf;


namespace PdfiumViewerDemo
{
        public class PdfSharpHelper
        {
            // const string facename = "Times New Roman";
            static string fontName = "华文宋体"; //华文宋体 Arial

            //左右边距
            const int padding_leftRight = 30;

            //上下边距
            const int padding_topBottom = 30;


            /// <summary>
            /// 保存为文件流
            /// </summary>
            /// <param name="binary"></param>
            /// <returns></returns>
            public static MemoryStream SaveToStream()
            {
                PdfDocument doc = new PdfDocument();
                CreatePdfSharpPDF( doc);

                MemoryStream stream = new MemoryStream();
                doc.Save(stream);
                return stream;
            }


            /// <summary>
            /// 绘制功能码表头
            /// </summary>
            /// <param name="document"></param>
            /// <param name="page"></param>
            /// <param name="startY"></param>
            /// <returns></returns>
            private static float DrawPDFCodeTitle(PdfPage page, XGraphics gfx, float startY)
            {
                float x = padding_leftRight;
                float y = startY;

                XFont Titlefont = new XFont(fontName, 9, XFontStyle.Bold);

                XSize size = gfx.MeasureString("Param", Titlefont);

                float endY = (float)size.Height * 2 + 5;
                //绘制标题
                gfx.DrawRectangle(XBrushes.LightCyan, new XRect(padding_leftRight, y,
                    page.Width - 2 * padding_leftRight, endY));

                y += (float)size.Height * 2 + 1;
                gfx.DrawString(" Parameter", Titlefont, XBrushes.Black, x, y);

                x += (float)(page.Width * 0.32);
                gfx.DrawString("Value", Titlefont, XBrushes.Black, x, y);

                // x += (float)(page.Width * 0.098);
                // gfx.DrawString("Infomation", Titlefont, XBrushes.Black, x, y);

                x += (float)(page.Width * 0.31);
                gfx.DrawString("Setting", Titlefont, XBrushes.Black, x, y);
                gfx.DrawString("Default", Titlefont, XBrushes.Black, x, y - size.Height - 1);


                return (endY + startY);
            }

            /// <summary>
            /// 绘制页脚
            /// </summary>
            /// <param name="page">页面</param>
            /// <param name="gfx">画布</param>
            /// <param name="cur">当前页序号</param>
            /// <param name="total">总的页码数</param>
            private static void DrawPDFFooter(PdfPage page, XGraphics gfx, int cur, int total)
            {
                //计算高度
                float endY = (float)page.Height - padding_topBottom;

                XFont Timefont = new XFont(fontName, 10, XFontStyle.Bold);

                //测量字符串大小
                XSize size = gfx.MeasureString("Drive Type/", Timefont);


                //绘制页脚
                gfx.DrawLine(new XPen(XColors.Black, 0.2f),
                    padding_leftRight,
                    endY,
                   page.Width - padding_leftRight,
                   endY);

                endY += 2 + (float)size.Height;

                //绘制信息
                String footerText = "Test for Windows(C) by 唠嗑一夏 Electric Corporation";
                gfx.DrawString(footerText, Timefont, XBrushes.Black, padding_leftRight,
                    endY);

                Timefont = new XFont(fontName, 10, XFontStyle.Regular);

                //绘制页码数
                footerText = cur.ToString() + "/" + total.ToString();
                gfx.DrawString(footerText, Timefont, XBrushes.Black,
                    (page.Width * 0.9), endY);
            }



            /// <summary>
            /// 数据表格
            /// </summary>
            /// <returns></returns>
            private static DataTable CreateData()
            {
                DataTable dt = new DataTable();
                DataColumn col1 = new DataColumn("Num", typeof(string));
                DataColumn col2 = new DataColumn("Name", typeof(string));
                DataColumn col3 = new DataColumn("Val", typeof(string));
                DataColumn col4 = new DataColumn("Des", typeof(string));
                DataColumn col5 = new DataColumn("Set", typeof(string));

                dt.Columns.Add(col1);
                dt.Columns.Add(col2);
                dt.Columns.Add(col3);
                dt.Columns.Add(col4);
                dt.Columns.Add(col5);

                Random random = new Random();
                List<string> nameList = new List<string>
            {
                "A", "BB", "CCC", "D",
                "E", "F", "G","H","II",
                "JJ", "LL", "M"
            };

                List<string> tempList = new List<string>
            {
                "dsd", "sdfdgvre", "Hello", "Gilrs",
                "Today", "YYYY", "dfgre","GSD","fdgfer",
                "Wesd", "DLG", "fsdahfi;o"
            };

                for (int i = 0; i < 10; i++)
                {
                    for (int j = 0; j < 10; j++)
                    {
                        DataRow dr = dt.NewRow();
                        dr[0] = "KK" + i.ToString("d2") + "." + j.ToString("d2");
                        dr[1] = nameList[j];
                        if (j % 3 == 0)
                        {
                            dr[2] = random.NextDouble().ToString("f3");
                        }
                        else
                        {
                            dr[2] = i * j - random.Next(0, 30);
                        }
                        dr[3] = tempList[j];

                        dr[4] = random.NextDouble().ToString("f2");

                        //添加新行
                        dt.Rows.Add(dr);
                    }
                }

                return dt;
            }


            /// <summary>
            /// 创建PDF
            /// </summary>
            public static void  CreatePdfSharpPDF(PdfDocument doc)
        {
                try
                {
                    //获取测试数据
                    DataTable dataTable = CreateData();

                    //创建文档对象
                  //  PdfDocument doc = new PdfDocument();
                    //创建空页
                    PdfPage page = doc.AddPage();
                    //设置纸张大小
                    page.Size = PageSize.A4;

                    List<XGraphics> gfxList = new List<XGraphics>();

                    //设置一个画布
                    XGraphics gfx = XGraphics.FromPdfPage(page);
                    gfxList.Add(gfx);

                    const string fontName = "华文宋体";
                    //设置字体
                    XFont Titlefont = new XFont(fontName, 14, XFontStyle.Bold);
                    XFont Timefont = new XFont(fontName, 12, XFontStyle.Regular);


                    //绘制标题
                    gfx.DrawString(" Parameter Settings Report(Program)", Titlefont, XBrushes.Black,
                        new XRect(padding_leftRight, 30, page.Width - padding_leftRight, 30),
                        XStringFormats.CenterLeft);

                    //日期
                    gfx.DrawString(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"), Timefont, XBrushes.Black,
                      new XRect(page.Width * 0.7, 30, page.Width * 0.3 - padding_leftRight, 30),
                      XStringFormats.BottomRight);

                    XPen linePen = new XPen(XColor.FromKnownColor(XKnownColor.Black), 0.1);
                    //绘制线
                    gfx.DrawLine(linePen,
                        new XPoint(padding_leftRight, 60), new XPoint(page.Width - padding_leftRight, 60));

                    //设置字体
                    Titlefont = new XFont(fontName, 12, XFontStyle.Bold);
                    Timefont = new XFont(fontName, 10, XFontStyle.Regular);

                    //测量字体的大小
                    XSize size = gfx.MeasureString("Program", Titlefont);
                    XSize size2 = gfx.MeasureString("Drive Type/", Timefont);


                    float y = 62;
                    float endY = (float)size.Height + 4 + (float)size2.Height;
                    //绘制矩形框和字符串
                    gfx.DrawRectangle(XBrushes.LightCyan, new XRect(padding_leftRight, y, page.Width - 2 * padding_leftRight, endY));
                    gfx.DrawString(" Program(Drive Selected / Connected)", Titlefont,
                        XBrushes.Black, padding_leftRight, y, XStringFormat.TopLeft);

                    y += 4 + (float)size.Height;
                    gfx.DrawString(" Drive Type/Model: ", Timefont,
                        XBrushes.Black, padding_leftRight, y, XStringFormat.TopLeft);


                    y += 4 + (float)size2.Height;
                    gfx.DrawLine(linePen,
                       new XPoint(padding_leftRight, y), new XPoint(page.Width - padding_leftRight, y));

                    y += 4;
                    gfx.DrawString(" Project: ", Titlefont,
                        XBrushes.Black, padding_leftRight, y, XStringFormat.TopLeft);

                    y += 4 + (float)size.Height;
                    gfx.DrawLine(linePen,
                      new XPoint(padding_leftRight, y), new XPoint(page.Width - padding_leftRight, y));

                    y += 4;
                    Titlefont = new XFont(fontName, 11, XFontStyle.Bold);
                    gfx.DrawString(" Information ", Titlefont,
                        XBrushes.Black, padding_leftRight, y, XStringFormat.TopLeft);

                    y += 100;

                    //项目的标题
                    y = DrawPDFCodeTitle(page, gfx, y) + 10;

                    //绘制功能码的字体
                    XFont funFont = new XFont(fontName, 9);
                    XFont FunBoldFont = new XFont(fontName, 9, XFontStyle.Underline | XFontStyle.Bold);

                    //字体的高度
                    XSize funcSize = gfx.MeasureString("KK00.00", funFont);
                    XSize funcBoldSize = gfx.MeasureString("KK00.00", FunBoldFont);

                    int count = dataTable.Rows.Count;
                    string str = "";
                    string strBak = "";
                    int j = 0;


                    for (int i = 0; i < count; i++)
                    {//遍历功能码
                        if ((y + funcSize.Height + 3) > (page.Height - padding_topBottom))
                        {//换页
                            page = doc.Pages.Add();
                            page.Size = PageSize.A4;
                            gfx = XGraphics.FromPdfPage(page);
                            gfxList.Add(gfx);
                            //绘制功能码表头
                            y = DrawPDFCodeTitle(page, gfx, 10) + 10;
                        }

                        DataRow dataRow = dataTable.Rows[i];
                        strBak = dataRow[0].ToString().Substring(0, 4);
                        if (strBak != str)
                        {//绘制功能码组
                            str = strBak;
                            string converStr = strBak;
                            j++;
                            funcBoldSize = gfx.MeasureString(converStr, FunBoldFont);
                            y += (float)funcBoldSize.Height + 6;

                            gfx.DrawString(converStr, FunBoldFont, XBrushes.Black, padding_leftRight, y);

                            y += 2;
                            i--;
                            continue;
                        }
                        // else
                        {//绘制

                            string tempStr = dataRow[0].ToString() + " " + dataRow[1].ToString();

                            funcSize = gfx.MeasureString(tempStr, funFont);
                            y += (float)funcSize.Height + 3;

                            if ((y + funcSize.Height + 3) > (page.Height - padding_topBottom))
                            {//换页
                                page = doc.Pages.Add();
                                page.Size = PageSize.A4;
                                gfx = XGraphics.FromPdfPage(page);

                                gfxList.Add(gfx);
                                //绘制功能码表头
                                y = DrawPDFCodeTitle(page, gfx, 10) + 10;
                            }

                            //序号+描述
                            float widthX = padding_leftRight;
                            gfx.DrawString(tempStr, funFont, XBrushes.Black, widthX, y);

                            //当前值
                            widthX += (float)(page.Width * 0.32);
                            gfx.DrawString(dataRow[2].ToString(), funFont, XBrushes.Black, widthX, y);

                            //设置值
                            widthX += (float)(page.Width * 0.31);
                            gfx.DrawString(dataRow[4].ToString(), funFont, XBrushes.Black, widthX, y);
                        }

                    }

                    gfx = null;
                    int Total = doc.PageCount;
                    for (int i = 0; i < Total; i++)
                    {//绘制页脚
                        DrawPDFFooter(page, gfxList[i], i + 1, Total);
                    }
                   // string path = "PdfSharpDemo.pdf";
                  //  doc.Save(path);
                }
                catch (Exception ex)
                {

                }

            }
        }
    }


将使用PdfSharp生成的PDF文件流,在PdfViewer中显示。

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 PdfiumViewer;

namespace PdfiumViewerDemo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            // 加载PDF文档
          // LoadPdfByDocument();
            LoadPdfByStream();
        }


       /// <summary>
       /// 加载本地PDF文档
       /// </summary>
        private void LoadPdfByDocument()
        {

            //创建一个PDFView控件
            PdfViewer pdfViewer1 = new PdfViewer();
            //设置位置和大小
            pdfViewer1.Location = new Point(5, 5);
            pdfViewer1.Size = new Size(200, 300);
            pdfViewer1.Dock = DockStyle.Fill;

            //将控件添加到界面上
            this.Controls.Add(pdfViewer1);

            //加载PDF文档
            pdfViewer1.Document = PdfDocument.Load(@"D:Demo.pdf");
        }



        /// <summary>
        /// 加载PDF文件流
        /// </summary>
        private void LoadPdfByStream()
        {
            //创建一个PDFView控件
            PdfViewer pdfViewer1 = new PdfViewer();
            //设置位置和大小
            pdfViewer1.Location = new Point(5, 5);
            pdfViewer1.Size = new Size(200, 300);
            pdfViewer1.Dock = DockStyle.Fill;

            //将控件添加到界面上
            this.Controls.Add(pdfViewer1);

            //加载PDF文件流
            pdfViewer1.Document = PdfDocument.Load(PdfSharpHelper.SaveToStream());
        }
    }
}

在这里插入图片描述

小节

主要记录PdfiumViewer对PDF文档打印预览的两种方法,一种是直接打开加载PDF文档,另外一种是加载PDF文件流(与PdfSharp配合使用)。
PdfiumViewer组件主要是使用PdfDocument.Load来加载PDF文档。

附录

PdfiumViewer GitHub链接:https://github.com/pvginkel/PdfiumViewer

C# 使用自带的组件PrintPreviewDialog 和 PrintDocument实现打印预览(一)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值