不吹不黑,学完这篇,PDF导出就没有问题了

  

写在前头:本篇仅记录作者开发过程中使用的导出策略(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:\Windows\Fonts文件夹下 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:今天就放年假了,祝大家新年快乐。

posted @ 2020-01-16 11:16  轩·尘  阅读(603)  评论(0编辑  收藏  举报