[ASP.net MVC] 将HTML转成PDF档案,使用iTextSharp套件的XMLWorkerHelper (附上解决显示中文问题)

原文:[ASP.net MVC] 将HTML转成PDF档案,使用iTextSharp套件的XMLWorkerHelper (附上解决显示中文问题)

[ASP.net MVC] 将HTML转成PDF档案,使用iTextSharp套件的XMLWorkerHelper (附上解决显示中文问题)

前言

最近专案又遇到需要制作PDF文件的需求,这次还要额外控制PDF档案的其他功能,我的直觉马上联想到使用iTextSharp来实现

一般使用iTextSharp套件要塞资料到PDF档案里的话,大概要先把Phrase、PdfPTable、PdfPCell……等等几个物件叫出来,然後加入至Document物件

※请参考其他网友文章:使用ASP .NET (C#) 产生PDF档的好帮手—iTextSharp library (上)使用ASP .NET (C#) 产生PDF档的好帮手—iTextSharp library (下)

但由於专案要求有 [网页预览+下载PDF(把预览的网页画面转出到PDF档)功能]

因为已经先有Html网页画面了,我比较懒,所以在网路上寻求有没有把Html网页转PDF档的iTextSharp实现办法

虽然过程中有考量用:[ASP.net MVC] 在Web专案上使用Pechkin套件将网页转成PDF档

但Pechkin没办法进一步控制PDF档案的详细功能,它只能仅仅印出来而已

所以整个需求大致是:利用iTextSharp套件将网页档(或HTML文字)转成PDF档

?

而iTextSharp一般在网路上比较常见,都是使用内建的HtmlWorker物件来实现

※HtmlWorker已有中文字显示问题的解决办法,请参考其他网友文章:使用iTextSharp 5将html档转成PDF档

但本文使用的是XMLWorkerHelper物件来Parse网页Html文字

因为比起HtmlWorker物件,XMLWorkerHelper类别支援更多CSS和Html标签(例如<hr/>),但缺点预设不支援中文字

不过中文字显示问题,已经在下文的Sample Code中解决了

?

实作

先为Web专案透过NuGet加入以下参考

以下是要输出成PDF档案的范例静态网页内容,还没套程式,因为套程式塞资料到画面不是本文的重点

此网页Html该注意的重点都在说明注解里

      <!--设定width为100%以刚好符合PDF文件的宽度-->
      <!--如果width为固定宽度的话,C#那边可能要改写成Document doc = new Document(PageSize.A3)-->
      <!--此table已调整好高度刚好符合PDF A4一页的高度了-->
      <table style='width:100%;'  >
        <tr >
            <td colspan='2' style='color:#808080;'>
               <h2>[厂商名称]</h2>
            </td>
        </tr>
        <tr style='font-size:13px;'>
         <td style='width:600px;color:#808080;font-size:16px;'>Taiwan Limited<br />4F,144 Changchun Rd., Taipei 104, Taiwan</td>
         <td style='width:80%;color:#808080;font-size:16px;text-align:right;'>[页码]/[总页数]</td>
         </tr>

        <tr>
            <td  colspan='2'  style='text-align:center; height:90px;'><h1>XXX借用函证书</h1></td>
        </tr>
        <tr>
            <td  colspan='2'  style='text-align:right;font-size:20px;'> 日期:民国[函证民国日期] </td>
        </tr>
        <tr>
            <td  colspan='2'  style='height:10px;font-size:20px;' > 敬启者:[经销商全衔] </td>
        </tr>
        <tr>
            <td  colspan='2'  style='height:30px;font-size:20px;'  > XXX 借用人:[员工姓名] </td>
        </tr>
         <tr>
            <td  colspan='2'  style='height:50px;line-height:27px;font-size:20px;vertical-align:bottom;' > [厂商名称]将於&nbsp;[存货盘点民国日期]&nbsp;进行例行性存货盘点,恳请协助清点敝公司借予&nbsp;&nbsp;贵公司之存货品名及数量是否与下列明细相符,并盖章回传以兹证明。 </td>
        </tr>
        <tr>
            <td  colspan='2'  style='height:40px;font-size:20px;' > 敬祝&nbsp;&nbsp;商祺 </td>
        </tr>
        <tr>
            <td  colspan='2'  style='height:30px;line-height:20px;font-size:20px;' > 此致&nbsp;&nbsp;[厂商名称] </td>
        </tr>
        <tr>
            <td  colspan='2'  style='font-size:20px;line-height:20px;'  > 以下为截至 民国[函证民国日期] 为止,贵公司借用之存货明细:  </td>
        </tr>
        <tr>
            <td  colspan='2'  style='height:280px;vertical-align:top;font-size:20px;'  >
                <table  style='border:1px solid #000000; width:100%;' cellpadding='0' cellspacing='0'>
                    <tr>
                        <td style='border:1px solid #000000;text-align:center;font-size:20px;'>No</td>
                        <td style='border:1px solid #000000;text-align:center;font-size:20px;'>品号</td>
                        <td style='border:1px solid #000000;text-align:center;font-size:20px;'>品名</td>
                        <td style='border:1px solid #000000;text-align:center;font-size:20px;'>数量</td>
                    </tr>
                </table>

            </td>
        </tr>
        <tr>
            <td  colspan='2'  style='font-size:20px;' > 确认无误,特此证明。  </td>
        </tr>
        <tr>
            <td  colspan='2'  style='height:200px; '      >
                <div style='float:right;'>
                <table style='border:1px solid #000000; ' cellpadding='0' cellspacing='0'>
                   <tr>
                       <td style='border:1px solid #000000;width:180px;height:180px;text-align:right; vertical-align:bottom;padding-bottom:10px;font-size:16px;'>经销商公司章</td>
                       <td style='border:1px solid #000000;width:180px;height:180px;text-align:right;vertical-align:bottom;padding-bottom:10px;font-size:16px;'>借用人签章</td>
                   </tr>
               </table>
                </div>
            </td>
        </tr>
        <tr>
            <td  colspan='2'  style='text-align:right;font-size:20px;'  > 民国[函证民国日期] </td>
        </tr>
        <tr style='font-size:13px;height:50px;'>
            <td  colspan='2'  style='color:#808080;font-size:16px; vertical-align:bottom;'   > 经销商代号: 出借者工号: </td>
        </tr>
    </table>

该Html静态网页的执行内容

※补充说明,以上最外层的table容器宽度如果是固定宽度而非100%宽,Document物件又设为PageSize.A4的话,输出成PDF很可能会变这样↓

↑这种情况虽然调参数Document doc=new Document(PageSize.A3);即可解决,但比较通用的办法还是把最外层的容器宽度设为100%以符合PDF各种A4 、A3大小的宽度

?

接下来在专案中加入一个自订类别UnicodeFontFactory.cs,待会输出PDF时要使用此类别来解决XMLWorkerHelper不支援中文字问题

UnicodeFontFactory.cs代码完整内容

using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.tool.xml;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;

    public class UnicodeFontFactory : FontFactoryImp
    {

        private static readonly string arialFontPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Fonts),
            "arialuni.ttf");//arial unicode MS是完整的unicode字型。
        private static readonly string 标楷体Path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Fonts),
          "KAIU.TTF");//标楷体

        public override Font GetFont(string fontname, string encoding, bool embedded, float size, int style, BaseColor color,
            bool cached)
        {
            //可用Arial或标楷体,自己选一个
            BaseFont baseFont = BaseFont.CreateFont(标楷体Path, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
            return new Font(baseFont, size, style, color);
        }

    }
 

而在HomeController里,Html转PDF的完整范例代码

using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.tool.xml;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Mvc;

namespace MvcApplicationPDF.Controllers
{
    public class HomeController : Controller
    {

        /// <summary>
        /// 执行此Url,下载PDF档案
        /// </summary>
        /// <returns></returns>
        public ActionResult DownloadPdf()
        {
            WebClient wc = new WebClient();
            //从网址下载Html字串
            string htmlText = wc.DownloadString("http://localhost:3056/Preview.html");
            byte[] pdfFile = this.ConvertHtmlTextToPDF(htmlText);

            return File(pdfFile, "application/pdf", "范例PDF档.pdf");
        }
        /// <summary>
        /// 将Html文字 输出到PDF档里
        /// </summary>
        /// <param name="htmlText"></param>
        /// <returns></returns>
        public  byte[] ConvertHtmlTextToPDF(string htmlText)
        {
            if (string.IsNullOrEmpty(htmlText))
            {
                return null;
            }
            //避免当htmlText无任何html tag标签的纯文字时,转PDF时会挂掉,所以一律加上<p>标签
            htmlText = "<p>" + htmlText + "</p>";

            MemoryStream outputStream = new MemoryStream();//要把PDF写到哪个串流
            byte[] data = Encoding.UTF8.GetBytes(htmlText);//字串转成byte[]
            MemoryStream msInput = new MemoryStream(data);
            Document doc = new Document();//要写PDF的文件,建构子没填的话预设直式A4
            PdfWriter writer = PdfWriter.GetInstance(doc, outputStream);
            //指定文件预设开档时的缩放为100%
            PdfDestination pdfDest = new PdfDestination(PdfDestination.XYZ, 0, doc.PageSize.Height, 1f);
            //开启Document文件
            doc.Open();
            //使用XMLWorkerHelper把Html parse到PDF档里
            XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, msInput, null, Encoding.UTF8, new UnicodeFontFactory());
            //将pdfDest设定的资料写到PDF档
            PdfAction action = PdfAction.GotoLocalPage(1, pdfDest, writer);
            writer.SetOpenAction(action);
            doc.Close();
            msInput.Close();
            outputStream.Close();
            //回传PDF档案
            return outputStream.ToArray();

        }

    }
}

执行结果:

 

结语

将Html转成PDF,使用Pechkin或iTextSharp各有优缺点

画面呈现当然是Pechkin比较忠於原始网页(因为采用Webkit引擎),如果没要进一步控制PDF档案功能的话,可使用Pechkin

如果要进一步控制PDF功能而且画面只是单纯的白纸黑字,就可以改用iTextSharp套件

 

参考文章

Display Unicode characters in converting Html to Pdf

How to set a default zoom percent to “100%” using iTextSharp 4.0.2?

时间: 2024-11-02 12:44:09

[ASP.net MVC] 将HTML转成PDF档案,使用iTextSharp套件的XMLWorkerHelper (附上解决显示中文问题)的相关文章

asp.net mvc 是否可以打包成安装程序

问题描述 平时在服务器上部署需要安装数据库.IIS..netframework.mvc版本,是否可以有办法打包成一个安装包,其中自带解析器,数据库可以做成本地的?用户点击图标即可执行通过浏览器打开? 解决方案 解决方案二:不带服务器?我看你数据库也别要了,做几个静态网页来实现吧解决方案三:.....感觉不太可行解决方案四:sqlserver好说,安装程序可以用命令行参数,.Net也可以用系统必备装上,IIS微软根本就没提供用于再发布的安装程序.你可以在安装程序里检测IIS是否安装.解决方案五:首

ASP.NET MVC中对Model进行分步验证的解决方法

在我之前的文章:ASP.NET MVC2.0结合WF4.0实现用户多步注册流程中将一个用 户的注册分成了四步,而这四个步骤都是在完善一个Model的信息,但是又分页面 填写信息的,当时我加上ModelState.IsValid这句验证代码的时候,根本没法通 过验证,因为在注册的前面三步,注册用户的Model信息都没填写完整,而 ModelState.IsValid是对一个实体的所有属性进行判断验证的.当时很纠结,因 为刚接触Asp.net MVC,故没有找到解决方案.这篇文章将给出解决的办法.看

word怎样转换成pdf技巧分享

word怎样转换成pdf技巧分享 现在大家的电脑上经常会准备一款pdf文件阅读工具,用来方便pdf文件内容的浏览,而在工作的时候,大家经常需要将各种办公文件制作成pdf文档,就比如将word文件转换成pdf,可是word怎样转换成pdf呢? 对于文件转换问题,小编有非常丰富的经验,这里小编就为大家介绍两种word文件转换成pdf文件方法,希望大家能够轻松解决文件转换问题,加快工作效率. (一)在线版word转换成pdf方法 图片1 迅捷在线PDF转换器是国内首个支持多文件格式转换的转换平台,支持

ASP.NET MVC 重点教程一周年版 第一回 安装,并使ASP.NET MVC页面运行起来

从前写过一系列的ASP.NET MVC教程,ASP.NET MVC在这之后历经5个preview版本终于到今天的RC版本,而且不久就要正式推出正式版本,所以值此之际,重典也重新修正这一系列的教程,使之与时俱进. 因为最初的一篇是写自2008年3月10日(Asp.net Mvc Framework 系列),回头看看已经足足一年了,所以本系列修正版本的教程就叫做ASP.NET MVC重典教程一周年版. 现在重开正文: 一.前ASP.NET MVC时代的故事 ASP.NET MVC是微软推出的基于AS

一起谈.NET技术,ASP.NET MVC中对Model进行分步验证的解决方法

在我之前的文章:ASP.NET MVC2.0结合WF4.0实现用户多步注册流程中将一个用户的注册分成了四步,而这四个步骤都是在完善一个Model的信息,但是又分页面填写信息的,当时我加上ModelState.IsValid这句验证代码的时候,根本没法通过验证,因为在注册的前面三步,注册用户的Model信息都没填写完整,而ModelState.IsValid是对一个实体的所有属性进行判断验证的.当时很纠结,因为刚接触Asp.net MVC,故没有找到解决方案.这篇文章将给出解决的办法.看下面需要验

ASP.Net MVC——使用 ITextSharp 完美解决HTML转PDF(中文也可以)

前言: 最近在做老师交代的一个在线写实验报告的小项目中,有这么个需求:把学生提交的实验报告(HTML形式)直接转成PDF,方便下载和打印. 以前都是直接用rdlc报表实现的,可这次牵扯到图片,并且更为重要的一点是 PDF的格式得跟学生提交的HMTL页面一样.经过网上查阅资料, 找到了ITextSharp插件. ITextSharp很强大,但是在处理HMTL中的 img标签时,src中只能是绝对路径.  解决方法我写在了另一篇文章中 正文: ITextSharp就不多介绍了.项目的链接下载链接为h

使用ASP VBScript 把word PPT doc 等文件下载成pdf格式

问题描述 我想做一个就是把办公软件(如word.ppt.doc等文件)下载下来后直接是pdf格式,请问我该如何做,工具是DW,数据库是Access,希望能帮我解决下,感激不尽,谢谢! 解决方案 解决方案二:表达的不清楚你要干什么,做网站?解决方案三:表达的不清楚办公软件是什么?doc文件是办公软件???office才是办公软件,doc不过是个文件而已而且这些文件在哪里,以什么格式存放的?你要做的是个什么东西,要从哪里获取这些文件?全都没说.而且不管前面具体是什么方式,你想"下载下来直接就变格式&

ASP.NET MVC Controllers and Actions

原文:ASP.NET MVC Controllers and Actions MVC应用程序里的URL请求是通过控制器Controller处理的,不管是请求视图页面的GET请求,还是传递数据到服务端处理的Post请求都是通过Controller来处理的,先看一个简单的Controlller: public class DerivedController : Controller { public ActionResult Index() { ViewBag.Message = "Hello fr

ASP.NET MVC中实现多个按钮提交的几种方法

有时候会遇到这种情况:在一个表单上需要多个按钮来完成不同的功能,比如一个简单的审批功能. 如果是用webform那不需要讨论,但asp.net mvc中一个表单只能提交到一个Action处理,相对比较麻烦点. 方法一:使用客户端脚本 比如我们在View中这样写: 代码<inputtype="submit"value="审核通过"onclick='this.form.action="<%=Url.Action("Action1"