前言:
最近在做老师交代的一个在线写实验报告的小项目中,有这么个需求:把学生提交的实验报告(HTML形式)直接转成PDF,方便下载和打印。
以前都是直接用rdlc报表实现的,可这次牵扯到图片,并且更为重要的一点是 PDF的格式得跟学生提交的HMTL页面一样。经过网上查阅资料,
找到了ITextSharp插件。
ITextSharp很强大,但是在处理HMTL中的 img标签时,src中只能是绝对路径。
解决方法我写在了另一篇文章中
正文:
下开始项目之前得添加 ITextSharp.dll和ITextSharp.xmlworker.dll 后者是解决中文用的
可以从NuGet中下载引用,具体方法就不介绍了。网上很多解决方案。
项目结构图:
下面先说下主要操作:
步骤:1、将本地的某个视图转成字符串。
2、将字符串整合成PDF的文档,并返回byte数组。
3、讲比特流写到HTTP内容主体的二进制流中去。
视图转字符串代码:
首先新建两个类,转字符串的逻辑主要在RenderViewToString方法中。
再新建一个控制器,调用刚刚写好的RenderViewToString方法。(后面会再新建一个HomeController,继承这个PdfViewController,再在HomeController的Action里调用ViewPdf就行)
"字符串转byte[]" (这个方法放在后面写的HomeController中)
其中XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, msInput, null, Encoding.UTF8, new UnicodeFontFactory());这段代码中的“UnicodeFontFactory”类,封装了中文字体的设置。代码如下:
再新建一个类,用来将比特流输出到response.OutputStream中:
现在来看一下HomeController
步骤二的ConvertHtmlTextToPDF方法,我就直接放在了这里面,没管那些设计原则了。上面代码中“Preview”是本地的一个视图,最好和HomeController在一个区域里面,不然得改步骤一的代码。
最后是我的前台部分的代码,写的很简单(Preview.cshtml)。
1
2
3
4
<code>@model HTML转PDF.Models.People</code>
<code> </code><code><!-- 下面是我机器上的绝对路径 --> </code>
<code><img src=</code><code>"E:\12.bmp"</code> <code>width=</code><code>"64"</code> <code>height=</code><code>"64"</code> <code>/></code>
<code><p>大家好,我叫</code><code>"@Model.Name"</code><code></p></code>
特别注意:关于跳转到我们写的“DownloadPdf”Action时,千万不要用ajax.ActionLink(坑了我好久)。不然会出现乱码,我也没找到解决方案。