Spire.pdf 等打印 pdf 的库需要付费,因此本篇文章是通过使用 Google 开源的 PDFium 项目实现打印, PDFium 项目开源且跨平台。
bblanchon.PDFium.Win32 则是一个使用 C# 封装了 PDFium 的库。
引入三个库:
1 2 3 4 5 6 |
<span class="token operator"><</span>ItemGroup<span class="token operator">></span> <span class="token operator"><</span><span class="token class-name">PackageReference</span> Include<span class="token operator">=</span><span class="token string">"bblanchon.PDFium.Win32"</span> Version<span class="token operator">=</span><span class="token string">"122.0.6259"</span> <span class="token operator">/</span><span class="token operator">></span> <span class="token operator"><</span><span class="token class-name">PackageReference</span> Include<span class="token operator">=</span><span class="token string">"PdfiumPrinter"</span> Version<span class="token operator">=</span><span class="token string">"1.4.1"</span> <span class="token operator">/</span><span class="token operator">></span> <span class="token operator"><</span><span class="token class-name">PackageReference</span> Include<span class="token operator">=</span><span class="token string">"System.Drawing.Common"</span> Version<span class="token operator">=</span><span class="token string">"7.0.0"</span> <span class="token operator">/</span><span class="token operator">></span> <span class="token operator"><</span><span class="token class-name">PackageReference</span> Include<span class="token operator">=</span><span class="token string">"Vanara.PInvoke.Printing"</span> Version<span class="token operator">=</span><span class="token string">"3.4.17"</span> <span class="token operator">/</span><span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>ItemGroup<span class="token operator">></span> |
理论上,如果使用了 bblanchon.PDFium.Win32 ,理论上会自动携带 PDFium 动态库,示例:
bblanchon.PDFium 还有其它系统下的封装库,会自动带上对应系统的 PDFium 动态库。
正常情况,编译项目之后,会自动在目录中带出这些动态库, 不过有些情况下,使用 Release 发布项目不会带出这些动态库。例如程序设置了框架为 net8.0-windows
或者编译的时候指定了系统和 CPU 架构,例如 dotnet publish -c Release -r win-x64
。
这个时候编译出来的程序是不会带出动态库的。
可以手动到这个仓库下载编译好的动态库:https://github.com/bblanchon/pdfium-binaries
然后手动放到项目的目录下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
├─runtimes │ ├─linux-arm │ │ └─native │ │ libpdfium.so │ │ │ ├─linux-arm64 │ │ └─native │ │ libpdfium.so │ │ │ ├─linux-musl-arm64 │ │ └─native │ │ libpdfium.so │ │ │ ├─linux-musl-x64 │ │ └─native │ │ libpdfium.so │ │ │ ├─linux-musl-x86 │ │ └─native │ │ libpdfium.so │ │ │ ├─linux-x64 │ │ └─native │ │ libpdfium.so │ │ │ ├─linux-x86 │ │ └─native │ │ libpdfium.so │ │ │ ├─win-arm64 │ │ └─native │ │ pdfium.dll │ │ │ ├─win-x64 │ │ └─native │ │ pdfium.dll │ │ │ └─win-x86 │ └─native │ pdfium.dll |
并不需要所以动态库都使用,比如我只需要在 win x64 下使用,则只需要复制这个文件到项目下面:
下面开始讲解代码。
定义两个传递配置的模型类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
<span class="token comment">/// <summary></span> <span class="token comment">/// 打印机配置</span> <span class="token comment">/// </summary></span> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">PrintOption</span> <span class="token punctuation">{</span> <span class="token comment">/// <summary></span> <span class="token comment">/// 打印机名称<br /></span> <span class="token comment">/// <para>如果为空,则使用默认打印机</para></span> <span class="token comment">/// </summary></span> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">string</span><span class="token punctuation">?</span></span> PrinterName <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/// <summary></span> <span class="token comment">/// 是否自动打印,即静默打印。</span> <span class="token comment">/// <para>默认使用静默打印。</para></span> <span class="token comment">/// </summary></span> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">bool</span></span> IsAutoPrint <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token comment">/// <summary></span> <span class="token comment">/// 是否彩色打印</span> <span class="token comment">/// </summary></span> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">bool</span><span class="token punctuation">?</span></span> Color <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/// <summary></span> <span class="token comment">/// 页边距</span> <span class="token comment">/// </summary></span> <span class="token keyword">public</span> <span class="token return-type class-name">Margins<span class="token punctuation">?</span></span> Margins <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/// <summary></span> <span class="token comment">/// 打印纸张大小名称。</span> <span class="token comment">/// <para><see cref="PaperName"/> 跟 <see cref="CustomSize"/> 二选一,<see cref="CustomSize"/> 优先级高。</para></span> <span class="token comment">/// </summary></span> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">string</span><span class="token punctuation">?</span></span> PaperName <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/// <summary></span> <span class="token comment">/// 自定义纸张大小。</span> <span class="token comment">/// <para><see cref="PaperName"/> 跟 <see cref="CustomSize"/> 二选一,<see cref="CustomSize"/> 优先级高</para></span> <span class="token comment">/// </summary></span> <span class="token keyword">public</span> <span class="token return-type class-name">Size<span class="token punctuation">?</span></span> CustomSize <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/// <summary></span> <span class="token comment">/// 打印方向设置为横向。</span> <span class="token comment">/// </summary></span> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">bool</span><span class="token punctuation">?</span></span> Landscape <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/// <summary></span> <span class="token comment">/// 要打印多少份,默认为 1 份。</span> <span class="token comment">/// </summary></span> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">short</span></span> Count <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">PrintImageOption</span> <span class="token punctuation">:</span> <span class="token type-list"><span class="token class-name">PrintOption</span></span> <span class="token punctuation">{</span> <span class="token comment">/// <summary></span> <span class="token comment">/// 用于指定在图像缩放或变换时使用的插值算法。</span> <span class="token comment">/// <para>Mode 和 Dpi 不冲突</para></span> <span class="token comment">/// </summary></span> <span class="token comment">/// <remarks></span> <span class="token comment">/// <see cref="InterpolationMode.Default"/> 使用默认的插值模式。通常为Bilinear。<br /></span> <span class="token comment">/// <see cref="InterpolationMode.Low"/>: 低质量的插值模式,用于快速处理较大的图像。<br /></span> <span class="token comment">/// <see cref="InterpolationMode.High"/>: 高质量的插值模式,用于确保在图像缩放或变换时获得更好的细节和平滑度。<br /></span> <span class="token comment">/// <see cref="InterpolationMode.Bilinear"/>: 双线性插值模式,以平均周围4个像素的颜色来计算新像素的颜色值。<br /></span> <span class="token comment">/// <see cref="InterpolationMode.Bicubic"/>: 双三次插值模式,以周围16个像素的颜色加权平均来计算新像素的颜色值。<br /></span> <span class="token comment">/// <see cref="InterpolationMode.NearestNeighbor"/>: 最近邻插值模式,使用与目标像素最接近的原始像素的颜色值。<br /></span> <span class="token comment">/// <see cref="InterpolationMode.HighQualityBilinear"/>: 高质量双线性插值模式,类似于Bilinear,但具有更好的质量。<br /></span> <span class="token comment">/// <see cref="InterpolationMode.HighQualityBicubic"/>: 高质量双三次插值模式,类似于Bicubic,但具有更好的质量。<br /></span> <span class="token comment">/// </remarks></span> <span class="token keyword">public</span> <span class="token return-type class-name">InterpolationMode<span class="token punctuation">?</span></span> Mode <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/// <summary></span> <span class="token comment">/// 分辨率,默认打印机 dpi 96,dpi 影响打印机打印的物理成像。</span> <span class="token comment">/// <para>Mode 和 Dpi 不冲突</para></span> <span class="token comment">/// </summary></span> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">int</span><span class="token punctuation">?</span></span> Dpi <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token number">300</span><span class="token punctuation">;</span> <span class="token comment">/// <summary></span> <span class="token comment">/// 自动缩放,如果图片过大,则会自动缩小;如果图片过小,则会自动放大。</span> <span class="token comment">/// </summary></span> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">bool</span></span> IsAutoScale <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
定义从 PrintOption 配置整理到打印机设置的函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
<span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">BuildOption</span><span class="token punctuation">(</span><span class="token class-name">PrintDocument</span> pd<span class="token punctuation">,</span> <span class="token class-name">PrintOption</span> printOption<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>printOption <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token keyword">return</span><span class="token punctuation">;</span> <span class="token comment">// 设置打印机名称</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">IsNullOrEmpty</span><span class="token punctuation">(</span>printOption<span class="token punctuation">.</span>PrinterName<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> pd<span class="token punctuation">.</span>PrinterSettings<span class="token punctuation">.</span>PrinterName <span class="token operator">=</span> printOption<span class="token punctuation">.</span>PrinterName<span class="token punctuation">;</span> pd<span class="token punctuation">.</span>DefaultPageSettings<span class="token punctuation">.</span>PrinterSettings<span class="token punctuation">.</span>PrinterName <span class="token operator">=</span> printOption<span class="token punctuation">.</span>PrinterName<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// 是否静默打印</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>printOption<span class="token punctuation">.</span>IsAutoPrint<span class="token punctuation">)</span> <span class="token punctuation">{</span> pd<span class="token punctuation">.</span>PrintController <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">StandardPrintController</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// 打印份数</span> pd<span class="token punctuation">.</span>PrinterSettings<span class="token punctuation">.</span>Copies <span class="token operator">=</span> printOption<span class="token punctuation">.</span>Count<span class="token punctuation">;</span> <span class="token comment">// 是否彩色打印</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>printOption<span class="token punctuation">.</span>Color <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> pd<span class="token punctuation">.</span>PrinterSettings<span class="token punctuation">.</span>SupportsColor<span class="token punctuation">)</span> <span class="token punctuation">{</span> pd<span class="token punctuation">.</span>PrinterSettings<span class="token punctuation">.</span>DefaultPageSettings<span class="token punctuation">.</span>Color <span class="token operator">=</span> printOption<span class="token punctuation">.</span>Color<span class="token punctuation">.</span><span class="token function">GetValueOrDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> pd<span class="token punctuation">.</span>DefaultPageSettings<span class="token punctuation">.</span>Color <span class="token operator">=</span> printOption<span class="token punctuation">.</span>Color<span class="token punctuation">.</span><span class="token function">GetValueOrDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// 是否横向打印</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>printOption<span class="token punctuation">.</span>Landscape <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> pd<span class="token punctuation">.</span>PrinterSettings<span class="token punctuation">.</span>DefaultPageSettings<span class="token punctuation">.</span>Landscape <span class="token operator">=</span> printOption<span class="token punctuation">.</span>Landscape<span class="token punctuation">.</span><span class="token function">GetValueOrDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> pd<span class="token punctuation">.</span>DefaultPageSettings<span class="token punctuation">.</span>Landscape <span class="token operator">=</span> printOption<span class="token punctuation">.</span>Landscape<span class="token punctuation">.</span><span class="token function">GetValueOrDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// 设置页边距</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>printOption<span class="token punctuation">.</span>Margins <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> pd<span class="token punctuation">.</span>PrinterSettings<span class="token punctuation">.</span>DefaultPageSettings<span class="token punctuation">.</span>Margins <span class="token operator">=</span> printOption<span class="token punctuation">.</span>Margins<span class="token punctuation">;</span> pd<span class="token punctuation">.</span>DefaultPageSettings<span class="token punctuation">.</span>Margins <span class="token operator">=</span> printOption<span class="token punctuation">.</span>Margins<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// 设置纸张大小</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>printOption<span class="token punctuation">.</span>CustomSize <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token class-name"><span class="token keyword">var</span></span> paper <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">PaperSize</span><span class="token punctuation">(</span><span class="token string">"custom"</span><span class="token punctuation">,</span> printOption<span class="token punctuation">.</span>CustomSize<span class="token punctuation">.</span>Value<span class="token punctuation">.</span>Width<span class="token punctuation">,</span> printOption<span class="token punctuation">.</span>CustomSize<span class="token punctuation">.</span>Value<span class="token punctuation">.</span>Height<span class="token punctuation">)</span> <span class="token punctuation">{</span> PaperName <span class="token operator">=</span> <span class="token string">"custom"</span><span class="token punctuation">,</span> RawKind <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span>PaperKind<span class="token punctuation">.</span>Custom <span class="token punctuation">}</span><span class="token punctuation">;</span> pd<span class="token punctuation">.</span>PrinterSettings<span class="token punctuation">.</span>DefaultPageSettings<span class="token punctuation">.</span>PaperSize <span class="token operator">=</span> paper<span class="token punctuation">;</span> pd<span class="token punctuation">.</span>DefaultPageSettings<span class="token punctuation">.</span>PaperSize <span class="token operator">=</span> paper<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>printOption<span class="token punctuation">.</span>PaperName <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">int</span></span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> pd<span class="token punctuation">.</span>PrinterSettings<span class="token punctuation">.</span>PaperSizes<span class="token punctuation">.</span>Count<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>pd<span class="token punctuation">.</span>PrinterSettings<span class="token punctuation">.</span>PaperSizes<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>PaperName <span class="token operator">==</span> printOption<span class="token punctuation">.</span>PaperName<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token class-name"><span class="token keyword">var</span></span> paper <span class="token operator">=</span> pd<span class="token punctuation">.</span>PrinterSettings<span class="token punctuation">.</span>PaperSizes<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span> pd<span class="token punctuation">.</span>PrinterSettings<span class="token punctuation">.</span>DefaultPageSettings<span class="token punctuation">.</span>PaperSize <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">PaperSize</span><span class="token punctuation">(</span>paper<span class="token punctuation">.</span>PaperName<span class="token punctuation">,</span> paper<span class="token punctuation">.</span>Width<span class="token punctuation">,</span> paper<span class="token punctuation">.</span>Height<span class="token punctuation">)</span><span class="token punctuation">;</span> pd<span class="token punctuation">.</span>DefaultPageSettings<span class="token punctuation">.</span>PaperSize <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">PaperSize</span><span class="token punctuation">(</span>paper<span class="token punctuation">.</span>PaperName<span class="token punctuation">,</span> paper<span class="token punctuation">.</span>Width<span class="token punctuation">,</span> paper<span class="token punctuation">.</span>Height<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
打印文字:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">PrintText</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span><span class="token punctuation">[</span><span class="token punctuation">]</span></span> text<span class="token punctuation">,</span> <span class="token class-name">PrintOption<span class="token punctuation">?</span></span> printOption<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>printOption <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> printOption <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">PrintOption</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">PrintDocument</span> pd <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">PrintDocument</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">BuildOption</span><span class="token punctuation">(</span>pd<span class="token punctuation">,</span> printOption<span class="token punctuation">)</span><span class="token punctuation">;</span> pd<span class="token punctuation">.</span>PrintPage <span class="token operator">+=</span> PrintTxt<span class="token punctuation">;</span> pd<span class="token punctuation">.</span><span class="token function">Print</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">PrintTxt</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> sender<span class="token punctuation">,</span> <span class="token class-name">PrintPageEventArgs</span> ev<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token class-name"><span class="token keyword">var</span></span> printFont <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">System<span class="token punctuation">.</span>Drawing<span class="token punctuation">.</span>Font</span><span class="token punctuation">(</span>System<span class="token punctuation">.</span>Drawing<span class="token punctuation">.</span>SystemFonts<span class="token punctuation">.</span>DefaultFont<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> System<span class="token punctuation">.</span>Drawing<span class="token punctuation">.</span>SystemFonts<span class="token punctuation">.</span>DefaultFont<span class="token punctuation">.</span>Size<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name"><span class="token keyword">float</span></span> linesPerPage <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token class-name"><span class="token keyword">float</span></span> yPos <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token class-name"><span class="token keyword">int</span></span> count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token class-name"><span class="token keyword">float</span></span> leftMargin <span class="token operator">=</span> ev<span class="token punctuation">.</span>MarginBounds<span class="token punctuation">.</span>Left<span class="token punctuation">;</span> <span class="token class-name"><span class="token keyword">float</span></span> topMargin <span class="token operator">=</span> ev<span class="token punctuation">.</span>MarginBounds<span class="token punctuation">.</span>Top<span class="token punctuation">;</span> <span class="token class-name"><span class="token keyword">string</span></span> line <span class="token operator">=</span> <span class="token keyword">string</span><span class="token punctuation">.</span>Empty<span class="token punctuation">;</span> <span class="token comment">// 计算高度,一页能够打印多少行</span> linesPerPage <span class="token operator">=</span> ev<span class="token punctuation">.</span>MarginBounds<span class="token punctuation">.</span>Height <span class="token operator">/</span> printFont<span class="token punctuation">.</span><span class="token function">GetHeight</span><span class="token punctuation">(</span>ev<span class="token punctuation">.</span>Graphics<span class="token operator">!</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name"><span class="token keyword">int</span></span> index <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// 打印每一行</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>count <span class="token operator"><</span> linesPerPage <span class="token operator">&&</span> index <span class="token operator"><</span> text<span class="token punctuation">.</span>Length<span class="token punctuation">)</span> <span class="token punctuation">{</span> line <span class="token operator">=</span> text<span class="token punctuation">[</span>index<span class="token punctuation">]</span><span class="token punctuation">;</span> yPos <span class="token operator">=</span> topMargin <span class="token operator">+</span> <span class="token punctuation">(</span>count <span class="token operator">*</span> printFont<span class="token punctuation">.</span><span class="token function">GetHeight</span><span class="token punctuation">(</span>ev<span class="token punctuation">.</span>Graphics<span class="token operator">!</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> ev<span class="token punctuation">.</span>Graphics<span class="token operator">!</span><span class="token punctuation">.</span><span class="token function">DrawString</span><span class="token punctuation">(</span>line<span class="token punctuation">,</span> printFont<span class="token punctuation">,</span> Brushes<span class="token punctuation">.</span>Black<span class="token punctuation">,</span> leftMargin<span class="token punctuation">,</span> yPos<span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringFormat</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> count<span class="token operator">++</span><span class="token punctuation">;</span> index<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">IsNullOrEmpty</span><span class="token punctuation">(</span>line<span class="token punctuation">)</span><span class="token punctuation">)</span> ev<span class="token punctuation">.</span>HasMorePages <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token keyword">else</span> ev<span class="token punctuation">.</span>HasMorePages <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
打印图片:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">PrintImage</span><span class="token punctuation">(</span><span class="token class-name">Stream<span class="token punctuation">[</span><span class="token punctuation">]</span></span> streams<span class="token punctuation">,</span> <span class="token class-name">PrintImageOption<span class="token punctuation">?</span></span> printOption<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>printOption <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> printOption <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">PrintImageOption</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">PrintDocument</span> pd <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">PrintDocument</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">BuildOption</span><span class="token punctuation">(</span>pd<span class="token punctuation">,</span> printOption<span class="token punctuation">)</span><span class="token punctuation">;</span> pd<span class="token punctuation">.</span>PrintPage <span class="token operator">+=</span> PrintImage<span class="token punctuation">;</span> pd<span class="token punctuation">.</span><span class="token function">Print</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">PrintImage</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> sender<span class="token punctuation">,</span> <span class="token class-name">PrintPageEventArgs</span> e<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>streams<span class="token punctuation">.</span>Length <span class="token operator">></span> <span class="token number">1</span><span class="token punctuation">)</span> e<span class="token punctuation">.</span>HasMorePages <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">var</span></span> stream <span class="token keyword">in</span> streams<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>stream<span class="token punctuation">.</span>CanSeek<span class="token punctuation">)</span> stream<span class="token punctuation">.</span><span class="token function">Seek</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> SeekOrigin<span class="token punctuation">.</span>Begin<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">System<span class="token punctuation">.</span>Drawing<span class="token punctuation">.</span>Image</span> image <span class="token operator">=</span> System<span class="token punctuation">.</span>Drawing<span class="token punctuation">.</span>Image<span class="token punctuation">.</span><span class="token function">FromStream</span><span class="token punctuation">(</span>stream<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">using</span> <span class="token class-name">Graphics</span> graphics <span class="token operator">=</span> e<span class="token punctuation">.</span>Graphics<span class="token operator">!</span><span class="token punctuation">;</span> <span class="token comment">// 高质量图片</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>printOption<span class="token punctuation">.</span>Mode <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> graphics<span class="token punctuation">.</span>InterpolationMode <span class="token operator">=</span> InterpolationMode<span class="token punctuation">.</span>HighQualityBicubic<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>printOption<span class="token punctuation">.</span>Dpi <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> pd<span class="token punctuation">.</span>DefaultPageSettings<span class="token punctuation">.</span>PrinterResolution<span class="token punctuation">.</span>X <span class="token operator">=</span> printOption<span class="token punctuation">.</span>Dpi<span class="token punctuation">.</span><span class="token function">GetValueOrDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> pd<span class="token punctuation">.</span>DefaultPageSettings<span class="token punctuation">.</span>PrinterResolution<span class="token punctuation">.</span>Y <span class="token operator">=</span> printOption<span class="token punctuation">.</span>Dpi<span class="token punctuation">.</span><span class="token function">GetValueOrDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>printOption<span class="token punctuation">.</span>IsAutoScale<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token class-name"><span class="token keyword">var</span></span> size <span class="token operator">=</span> <span class="token function">GetSize</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>PageBounds<span class="token punctuation">,</span> image<span class="token punctuation">)</span><span class="token punctuation">;</span> graphics<span class="token punctuation">.</span><span class="token function">DrawImage</span><span class="token punctuation">(</span>image<span class="token punctuation">,</span> e<span class="token punctuation">.</span>MarginBounds<span class="token punctuation">.</span>X<span class="token punctuation">,</span> e<span class="token punctuation">.</span>MarginBounds<span class="token punctuation">.</span>Y<span class="token punctuation">,</span> size<span class="token punctuation">.</span>Width<span class="token punctuation">,</span> size<span class="token punctuation">.</span>Height<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// 不支持过大的图片跨页</span> graphics<span class="token punctuation">.</span><span class="token function">DrawImage</span><span class="token punctuation">(</span>image<span class="token punctuation">,</span> e<span class="token punctuation">.</span>MarginBounds<span class="token punctuation">.</span>X<span class="token punctuation">,</span> e<span class="token punctuation">.</span>MarginBounds<span class="token punctuation">.</span>Y<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token return-type class-name">Size</span> <span class="token function">GetSize</span><span class="token punctuation">(</span><span class="token class-name">Rectangle</span> page<span class="token punctuation">,</span> <span class="token class-name">Image</span> image<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token class-name"><span class="token keyword">double</span></span> imageWidth <span class="token operator">=</span> image<span class="token punctuation">.</span>Width<span class="token punctuation">;</span> <span class="token class-name"><span class="token keyword">double</span></span> imageHeight <span class="token operator">=</span> image<span class="token punctuation">.</span>Height<span class="token punctuation">;</span> <span class="token comment">// ClientSize 获取到的才是真正可以显示的区域,去掉了边框,Size 是纸张全部区域</span> <span class="token class-name"><span class="token keyword">double</span></span> pageWidth <span class="token operator">=</span> page<span class="token punctuation">.</span>Width<span class="token punctuation">;</span> <span class="token class-name"><span class="token keyword">double</span></span> pageHeight <span class="token operator">=</span> page<span class="token punctuation">.</span>Height<span class="token punctuation">;</span> <span class="token comment">// 最终计算结果</span> <span class="token class-name"><span class="token keyword">double</span></span> width <span class="token operator">=</span> image<span class="token punctuation">.</span>Width<span class="token punctuation">;</span> <span class="token class-name"><span class="token keyword">double</span></span> height <span class="token operator">=</span> image<span class="token punctuation">.</span>Height<span class="token punctuation">;</span> <span class="token comment">// 图片过长时</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>imageWidth <span class="token operator">>=</span> pageWidth<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token class-name"><span class="token keyword">double</span></span> ratio <span class="token operator">=</span> imageWidth <span class="token operator">/</span> pageWidth<span class="token punctuation">;</span> width <span class="token operator">=</span> pageWidth<span class="token punctuation">;</span> height <span class="token operator">=</span> imageHeight <span class="token operator">/</span> ratio<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// 图片小于页面,则自动放大</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>imageWidth <span class="token operator"><</span> pageWidth<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token class-name"><span class="token keyword">double</span></span> ratio <span class="token operator">=</span> pageWidth <span class="token operator">/</span> imageWidth<span class="token punctuation">;</span> width <span class="token operator">=</span> pageWidth<span class="token punctuation">;</span> height <span class="token operator">=</span> imageHeight <span class="token operator">*</span> ratio<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Size</span><span class="token punctuation">(</span><span class="token named-parameter punctuation">width</span><span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span>width<span class="token punctuation">,</span> <span class="token named-parameter punctuation">height</span><span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span>height<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
打印 pdf:
1 2 3 4 5 6 7 8 |
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">PrintPdf</span><span class="token punctuation">(</span><span class="token class-name">Stream</span> stream<span class="token punctuation">,</span> <span class="token class-name">PrintOption</span> printOption<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>printOption <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> printOption <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">PrintOption</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">PdfDocument</span> doc <span class="token operator">=</span> PdfDocument<span class="token punctuation">.</span><span class="token function">Load</span><span class="token punctuation">(</span>stream<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name"><span class="token keyword">var</span></span> printDocument <span class="token operator">=</span> doc<span class="token punctuation">.</span><span class="token function">CreatePrintDocument</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">BuildOption</span><span class="token punctuation">(</span>printDocument<span class="token punctuation">,</span> printOption<span class="token punctuation">)</span><span class="token punctuation">;</span> printDocument<span class="token punctuation">.</span><span class="token function">Print</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
由于生成的文件带有一些动态库,导致体积太大,不需要的情况下可以使用脚本自动删除。
1 2 3 4 |
<span class="token tag"><span class="token punctuation"><</span>Target <span class="token attr-name">Name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>DeletePdfiumFile<span class="token punctuation">"</span></span> <span class="token attr-name">AfterTargets</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>Publish<span class="token punctuation">"</span></span> <span class="token attr-name">Condition</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token punctuation">'</span>$(PublishDir)<span class="token punctuation">'</span> != <span class="token punctuation">'</span><span class="token punctuation">'</span><span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token punctuation"><</span>Exec <span class="token attr-name">WorkingDirectory</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>./<span class="token punctuation">"</span></span> <span class="token attr-name">Command</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>echo <span class="token punctuation">"</span></span><span class="token attr-name">DEL</span> <span class="token attr-name">$(PublishDir)libpdfium.dylib""</span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token punctuation"><</span>Exec <span class="token attr-name">WorkingDirectory</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>./<span class="token punctuation">"</span></span> <span class="token attr-name">Command</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>DEL <span class="token punctuation">"</span></span><span class="token attr-name">$(PublishDir)libpdfium.dylib""</span> <span class="token attr-name">ContinueOnError</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>true<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token punctuation"></</span>Target<span class="token punctuation">></span></span> |
写到主项目的 .csproj 文件中。
如果只需要 x64 不需要 x86,那么还可以减小体积。
1 2 3 4 5 6 7 |
<span class="token tag"><span class="token punctuation"><</span>Target <span class="token attr-name">Name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>DeletePdfiumFile<span class="token punctuation">"</span></span> <span class="token attr-name">AfterTargets</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>Publish<span class="token punctuation">"</span></span> <span class="token attr-name">Condition</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token punctuation">'</span>$(PublishDir)<span class="token punctuation">'</span> != <span class="token punctuation">'</span><span class="token punctuation">'</span><span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token punctuation"><</span>Exec <span class="token attr-name">WorkingDirectory</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>./<span class="token punctuation">"</span></span> <span class="token attr-name">Command</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>echo <span class="token punctuation">"</span></span><span class="token attr-name">删除pdfium文件""</span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token punctuation"><</span>Exec <span class="token attr-name">WorkingDirectory</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>./<span class="token punctuation">"</span></span> <span class="token attr-name">Command</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>echo <span class="token punctuation">"</span></span><span class="token attr-name">DEL</span> <span class="token attr-name">$(PublishDir)x86\pdfium.dll""</span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token punctuation"><</span>Exec <span class="token attr-name">WorkingDirectory</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>./<span class="token punctuation">"</span></span> <span class="token attr-name">Command</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>DEL <span class="token punctuation">"</span></span><span class="token attr-name">$(PublishDir)x86\pdfium.dll""</span> <span class="token attr-name">ContinueOnError</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>true<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token punctuation"><</span>Exec <span class="token attr-name">WorkingDirectory</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>./<span class="token punctuation">"</span></span> <span class="token attr-name">Command</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>echo <span class="token punctuation">"</span></span><span class="token attr-name">DEL</span> <span class="token attr-name">$(PublishDir)libpdfium.dylib""</span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token punctuation"><</span>Exec <span class="token attr-name">WorkingDirectory</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>./<span class="token punctuation">"</span></span> <span class="token attr-name">Command</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>DEL <span class="token punctuation">"</span></span><span class="token attr-name">$(PublishDir)libpdfium.dylib""</span> <span class="token attr-name">ContinueOnError</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>true<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token punctuation"></</span>Target<span class="token punctuation">></span></span> |
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。