因个人需求,需要将html格式转换成PDF并加上水印图片。于是乎第一次接触这种需求的小菜鸟博主我,在某度搜索引擎上不断地查阅关键字资料、踩坑,终于有了一个相应的解决方案。以下是解决步骤,记录下来方便以后的回顾,以及各位大神们的品鉴。
1、在 NuGet 搜索 itextsharp 关键字 下载以下截图圈中的两个包,一般下载完后项目会自动引用。
2、在项目文件中引入以下命名空间(建议下面提及的代码封装成类库,方便项目间调用,个人取舍)
3、Html字符串转pdf文件流,加水印图片以及未加水印重载 精简帮助类(由博主踩坑整理,仅完成个人业务需求)
1 ///
12 ///
31 ///
网页代码41 ///
水印路径42 ///
距离左边距离43 ///
距顶部距离44 ///
水印宽度45 ///
水印高度46 ///
标签54 htmlText = "
" + htmlText + "
";55 MemoryStream outputStream = new MemoryStream();//要把PDF写到哪个串流56 byte[] data = Encoding.UTF8.GetBytes(htmlText);//字串转成byte[]57 MemoryStream msInput = new MemoryStream(data);58 Document doc = new Document();//要写PDF的文件,建构子没填的话预设直式A459 PdfWriter writer = PdfWriter.GetInstance(doc, outputStream);60 //指定文件预设开档时的缩放为100%61 PdfDestination pdfDest = new PdfDestination(PdfDestination.XYZ, 0, doc.PageSize.Height, 1f);62 //开启Document文件 63 doc.Open();64 65 //写入水印图片66 if (!string.IsNullOrEmpty(picPath))67 {68 Image img = Image.GetInstance(picPath);69 //设置图片的位置70 img.SetAbsolutePosition(width + left, (doc.PageSize.Height - height) - top);71 //设置图片的大小72 img.ScaleAbsolute(width, height);73 doc.Add(img);74 }75 try76 {77 //使用XMLWorkerHelper把Html parse到PDF档里79 XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, msInput, null, Encoding.UTF8);80 //将pdfDest设定的资料写到PDF档81 PdfAction action = PdfAction.GotoLocalPage(1, pdfDest, writer);82 writer.SetOpenAction(action);83 }84 catch (Exception)85 {86 return null;87 }88 doc.Close();89 msInput.Close();90 outputStream.Close();91 //回传PDF档案 92 return outputStream.ToArray();94 }95 96 #endregion97 98 }4、获取网页字符串的方法
1 ///
5、MVC设计模式下获取控制器视图Html方法,很XX的一个问题就是只能获取调用此方法的控制器下所有视图,不能跨控制器获取视图,有待优化
1 ///
控制器上下文 5 ///
视图名称 6 ///
7 ///
6、将pdf流输出至客户浏览器下载方法
1 ///
PDF文件流 5 public static void PdfDownload(byte[] pdfFile) 6 { 7 byte[] buffer = pdfFile; 8 Stream iStream = new MemoryStream(buffer); 9 try10 {11 int length;12 long dataToRead;13 string filename = DateTime.Now.ToString("yyyyMMddHHmmss") + ".pdf";//保存的文件名称14 dataToRead = iStream.Length;15 HttpContext.Current.Response.Clear();16 HttpContext.Current.Response.ClearHeaders();17 HttpContext.Current.Response.ClearContent();18 HttpContext.Current.Response.ContentType = "application/pdf"; //文件类型 19 HttpContext.Current.Response.AddHeader("Content-Length", dataToRead.ToString());//添加文件长度,进而显示进度 20 HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(filename, Encoding.UTF8));21 while (dataToRead > 0)22 {23 if (HttpContext.Current.Response.IsClientConnected)24 {25 length = buffer.Length;26 HttpContext.Current.Response.OutputStream.Write(buffer, 0, length);27 HttpContext.Current.Response.Flush();28 buffer = new Byte[length];29 dataToRead = dataToRead - length;30 }31 else32 {33 dataToRead = -1;34 }35 }36 }37 catch (Exception ex)38 {39 HttpContext.Current.Response.Write("文件下载时出现错误!");40 }41 finally42 {43 if (iStream != null)44 {45 iStream.Close();46 }47 //结束响应,否则将导致网页内容被输出到文件,进而文件无法打开 48 HttpContext.Current.Response.Flush();49 HttpContext.Current.Response.End();50 51 }52 }
7、MVC控制器下调用Demo(步骤4、6 方法封装至帮助类)
1 public class HomeController : Controller 2 { 3 // 4 // GET: /Home/ 5 6 public ActionResult Index() 7 { 8 //从网址下载Html字符串(方法一) 9 string inpath = System.Web.HttpContext.Current.Server.MapPath("~/PDFTemplate/test.html");10 string htmlText = HtmlToPdfHelper.GetWebContent(inpath);//此处调用步骤4方法11 12 //获取MVC视图Html字符串(方法二)13 //string htmlText = GetViewHtml(ControllerContext, "Test");//此处调用步骤5方法14 15 //水印图片路径16 string picPath = Server.MapPath("~/PDFTemplate/TemplateImg/authentication-iocn.png");17 //html转pdf并加上水印18 byte[] pdfFile = HtmlToPdfHelper.ConvertHtmlTextToPdf(htmlText, picPath, 100, 200, 100, 100);19 //输出至客户端20 HtmlToPdfHelper.PdfDownload(pdfFile);//此处调用步骤6方法21 22 return View();23 }24 25 public ActionResult Test()26 {27 return View();28 }29 30 ///
34 ///
视图名称35 ///
总结:我理解的解决思路是将html读取转换成字符串,之后再通过 itextsharp 转换成 pdf 比特币 传输至客户端或直接保存至服务器生成链接供用户下载。(新手上路,不妥之处,欢迎各位大神指教)
以上代码仅满足个人业务逻辑需求,谢谢浏览。