使用iTextSharp结合XmlWork生成PDF文件

所属源码: iTextSharp
sam 2022-03-30 09:13:26

概述:

使用Html为模板,采用iTextSharp将一个Html模板生成Pdf文件

代码:(这个代码来源于网络,仅做使用)

原代码如下:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.tool.xml;
using iTextSharp.tool.xml.html;

namespace Eqiupment.Service
{
    /// <summary>
    /// HTML转PDF帮助类
    /// </summary>
    public class HtmlToPdfHelper
    {
        /// <summary>
        /// 准备好的html字符串
        /// </summary>
        private string m_HtmlString;

        /// <summary>
        /// PDF保存目录(绝对路径)
        /// </summary>
        private string m_PDFSaveFloder;

        /// <summary>
        /// 图片XY字典,例如 [{img1, 100,200},{img2,20,30}}
        /// </summary>
        private Dictionary<string, Tuple<float, float>> m_ImageXYDic = null;

        /// <summary>
        /// PDF保存目录(绝对路径)
        /// </summary>
        private string FileName;

        public HtmlToPdfHelper(string htmlString, string pdfSaveFloder, Dictionary<string, Tuple<float, float>> imageXYDic, string fileName)
        {
            m_HtmlString = htmlString;
            m_PDFSaveFloder = pdfSaveFloder;
            m_ImageXYDic = imageXYDic;
            FileName = fileName;
        }

        //生成PDF
        public bool BuilderPDF()
        {
            try
            {
                string pdfSavePath = Path.Combine(m_PDFSaveFloder, FileName + ".pdf");
                if (!Directory.Exists(m_PDFSaveFloder))
                {
                    Directory.CreateDirectory(m_PDFSaveFloder);
                }
                using (FileStream fs = new FileStream(pdfSavePath, FileMode.OpenOrCreate))
                {
                    byte[] htmlByte = ConvertHtmlTextToPDF(m_HtmlString);
                    string HTML = Encoding.UTF8.GetString(htmlByte);
                    fs.Write(htmlByte, 0, htmlByte.Length);
                    return true;
                }
            }
            catch (Exception ex)
            {
                throw new ApplicationException("保存PDF到磁盘时异常", ex);
            }
        }

        //将html字符串转为字节数组(代码来自百度)
        private byte[] ConvertHtmlTextToPDF(string htmlText)
        {
            if (string.IsNullOrEmpty(htmlText))
            {
                return null;
            }
            //避免當htmlText無任何html tag標籤的純文字時,轉PDF時會掛掉,所以一律加上<p>標籤
            htmlText = "<p>" + htmlText + "</p>";

            try
            {

                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();
                //使用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);
                doc.Close();
                msInput.Close();
                outputStream.Close();
                //回傳PDF檔案 
                return outputStream.ToArray();
            }
            catch (Exception ex)
            {
                throw new ApplicationException("转PDF时异常", ex);
            }
        }

        //字体工厂(代码来自百度)
        public class UnicodeFontFactory : FontFactoryImp
        {
            private static readonly string arialFontPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory
                , "fonts/arialuni.ttf");//arial unicode MS是完整的unicode字型。
            private static readonly string 标楷体Path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
           "fonts/kaiu.ttf");//标楷体

            public override Font GetFont(string fontname, string encoding, bool embedded, float size, int style, BaseColor color,
                bool cached)
            {
                BaseFont baseFont = BaseFont.CreateFont(arialFontPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
                return new Font(baseFont, size, style, color);
            }
        }

        //自定义的图片处理类(代码来自百度)
        public class CustomImageTagProcessor : iTextSharp.tool.xml.html.Image
        {
            //个人加入的图片位置处理代码
            private float _offsetX = 0;
            private float _offsetY = 0;

            private Dictionary<string, Tuple<float, float>> _imageXYDict;//个人加入的图片位置处理代码
            public CustomImageTagProcessor(Dictionary<string, Tuple<float, float>> imageXYDict)//个人加入的图片位置处理代码
            {
                _imageXYDict = imageXYDict;
            }

            protected void SetImageXY(string imageId)//个人加入的图片位置处理代码
            {
                if (_imageXYDict == null)
                {
                    return;
                }
                Tuple<float, float> xyTuple = null;
                _imageXYDict.TryGetValue(imageId, out xyTuple);

                if (xyTuple != null)
                {
                    _offsetX = xyTuple.Item1;
                    _offsetY = xyTuple.Item2;
                }
            }

            public override IList<IElement> End(IWorkerContext ctx, Tag tag, IList<IElement> currentContent)
            {
                IDictionary<string, string> attributes = tag.Attributes;
                string src;
                if (!attributes.TryGetValue(HTML.Attribute.SRC, out src))
                    return new List<IElement>(1);

                if (string.IsNullOrEmpty(src))
                    return new List<IElement>(1);

                string imageId;//个人加入的图片位置处理代码
                if (!attributes.TryGetValue(HTML.Attribute.ID, out imageId))//个人加入的图片位置处理代码
                    return new List<IElement>(1);

                if (string.IsNullOrEmpty(imageId))
                    return new List<IElement>(1);

                SetImageXY(imageId);//个人加入的图片位置处理代码

                if (src.StartsWith("data:image/", StringComparison.InvariantCultureIgnoreCase))
                {
                    // data:[][;charset=][;base64],
                    var base64Data = src.Substring(src.IndexOf(",") + 1);
                    var imagedata = Convert.FromBase64String(base64Data);
                    iTextSharp.text.Image.GetInstance(imagedata);
                    var image = iTextSharp.text.Image.GetInstance(imagedata);

                    var list = new List<IElement>();
                    var htmlPipelineContext = GetHtmlPipelineContext(ctx);
                    list.Add(GetCssAppliers().Apply(new Chunk((iTextSharp.text.Image)GetCssAppliers().Apply(image, tag, htmlPipelineContext), _offsetX, _offsetY, true), tag, htmlPipelineContext));
                    return list;
                }
                else
                {
                    return base.End(ctx, tag, currentContent);
                }


            }
        }
    }
}

根据Html生成Pdf,此例中,Html使用视图来产生

            StringBuilder sbInfo = new StringBuilder();
            string htmlInfo = HttpHelper.GetHtml("http://localhost:13028/devtest/tplhtml", "utf-8");
            HtmlToPdfHelper htmlToPdfHelper = new HtmlToPdfHelper(htmlInfo, "d:\\tmp", null, "11.pdf");
            htmlToPdfHelper.BuilderPDF();

结果

回帖
  • 消灭零回复
相关文章