写在前头:本篇仅记录作者开发过程中使用的导出策略(B/S)。
本篇仅记录PDF,查阅其他请跳转
导出PDF的方式也有很多,但是这里我要说的是 iText 方式,同样是使用的特殊字符替换法,首先准备模板,这里的模板怎么准备呢,因为是pdf,所以这里准备html静态模板,使用html做出合同的样式,手写吗?当然不是了,这里就介绍一种神器:富文本编辑器,无需下载,在线生成,只需要将咱们的word形式的模板全选复制,粘贴到文本编辑器中,转换成html,哪里不满意再微调格式就行啦。
哦,对了如果有不定行表格的话,不定行的位置都用一个特殊字符代替,然后再做一个该行的html模板,到时候用此模板直接替换特殊字符就好啦。
首先,获取咱们的html静态模板,
Assembly asm = Assembly.GetExecutingAssembly();//读取资源 Stream msgStream = asm.GetManifestResourceStream("Template.ContractTemplate.html"); StreamReader msgReader = new StreamReader(msgStream); string html = msgReader.ReadToEnd();
然后将咱们的不定行获取一下
var productHtml = string.Empty; Stream proStream=asm.GetManifestResourceStream("Template.ContractProductTemplate.html"); StreamReader proReader = new StreamReader(proStream); string proHtml = proReader.ReadToEnd(); //循环添加产品行 foreach (var item in model.ProductList) { var product = proHtml.Replace("${ItemName}$", item.ItemName) .Replace("${ProductName}$", item.InvStd) .Replace("${InvStd}$", item.InvStdOut) .Replace("${Unit}$", item.Unit) .Replace("${ItemNumber}$", GetNormalNum(item.ItemNumber.ToString())) .Replace("${TotalAmount}$", GetNormalNum(item.TotalAmount.ToString())); productHtml += product; }
获取之后,将主模板中的特殊字符替换
html = html.Replace("${lstTerm}$", str) .Replace("${productHeadStr}$", productHeadStr) .Replace("${contractCode}$", model.ContractCode) .Replace("${contractTime}$", Date.ToString("yyyy年MM月dd日")) .Replace("${address}$", model.ContractAddress) .Replace("${product}$", productHtml); return html;
这样,整个文件的html版就做好了,接下来就是将这些内容输出到PDF文档,这里是找的前人的代码,谢谢
/// <summary> /// 将Html字符串 输出到PDF档里,并添加水印 /// </summary> /// <param name="htmlText">网页代码</param> /// <param name="picPath">水印路径</param> /// <param name="left">距离左边距离</param> /// <param name="top">距顶部距离</param> /// <param name="width">水印宽度</param> /// <param name="height">水印高度</param> /// <returns></returns> public static byte[] ConvertHtmlTextToPdf(string htmlText, string picPath, int left, int top, int width, int height) { 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(); //写入水印图片 if (!string.IsNullOrEmpty(picPath)) { Image img = Image.GetInstance(picPath); //设置图片的位置 img.SetAbsolutePosition(width + left, (doc.PageSize.Height - height) - top); //设置图片的大小 img.ScaleAbsolute(width, height); doc.Add(img); } try { //使用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); } catch (Exception e) { return null; } doc.Close(); msInput.Close(); outputStream.Close(); //回传PDF档案 return outputStream.ToArray(); }
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");//標楷體是咱们电脑上的一种字体,默认存在的,如果这里报错的话,就去下载一下这个字体,然后复制到C:WindowsFonts文件夹下 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); } }
这样,PDF文档就可以得到了,导出的时候记得将文件名后缀设置成.pdf
好了,导出的话,就这些了,还有些iText具体的知识,还是百度自行学习吧。
仅供学习交流,欢迎留言指正!
PS:今天就放年假了,祝大家新年快乐。