zoukankan      html  css  js  c++  java
  • 不吹不黑,学完这篇,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: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:今天就放年假了,祝大家新年快乐。

    好好学习,认真笔记
  • 相关阅读:
    聊聊LiteOS事件模块的结构体、初始化及常用操作
    有了这个数据强一致“利器”,DBA们轻松修复数据对加班“say no”
    开源一周岁,MindSpore新特性巨量来袭
    90后就敢当扫地僧!不服?4月24号来闯龙门阵!
    你的数仓函数结果不稳定,可能是属性指定错了
    云小课 | 不了解EIP带宽计费规则?看这里!
    腾讯 angel 3.0:高效处理模型
    深度树匹配模型(TDM)
    X-Deep Learning功能模块
    XLearning
  • 原文地址:https://www.cnblogs.com/xuanyuandai/p/12200146.html
Copyright © 2011-2022 走看看