使用iText5来处理PDF

2019-03-21 10:31:21 浏览数 (2)

项目要求,通过pdf模板,把用户提交的数据保存到一个PDF文件中。其中有文字内容,也有图片。之前选了aspose.pdf,因为抠门,不能花钱买,就从网上找的的开心版,好不容易出来点模板,结果插入图片的时候,同一页只能插入一张图片,而官方的试用版是可以正常两张的,另外字段比较多,速度比较慢,几百个字段需要一分多钟,效率很低,放弃。之后尝试iText,发现要比aspose.pdf好用的多,下面就说下用法。

需要通过nuget安装iTextSharp,选第一个,版本号是5.5.12,也就是iText5版本,该版本是AGPL许可。

完整代码如下:

代码语言:javascript复制
using iTextSharp.text;
using iTextSharp.text.pdf;
using System.IO;

namespace Tools
{
    public class iTextPdf
    {
        Document pdfDocument = new Document();
        private string _path = "";

        #region 内容属性
        /// <summary>
        /// 文字
        /// </summary>
        public string Content { get; set; }

        /// <summary>
        /// X坐标
        /// </summary>
        public float X { get; set; }

        /// <summary>
        /// Y坐标
        /// </summary>
        public float Y { get; set; }

        /// <summary>
        /// 页索引(从0开始)
        /// </summary>
        public int PageIndex { get; set; }

        /// <summary>
        /// 类型
        /// 1-文字
        /// 2-勾选(图片)
        /// 3-签名
        /// 4-身份证正面
        /// 5-身份证反而
        /// </summary>
        public int Type { get; set; }

        /// <summary>
        /// 字体大小
        /// </summary>
        public float textSize { get; set; }

        /// <summary>
        /// 宽度(图片使用)
        /// </summary>
        public float Width { get; set; }

        /// <summary>
        /// 高度(图片使用)
        /// </summary>
        public float Height { get; set; }
        #endregion


        public iTextPdf()
        {
            _path = string.Format("{0}/template.pdf", System.Web.HttpContext.Current.Request.MapPath(System.Web.Configuration.WebConfigurationManager.AppSettings["ConfigDir"]));
        }

        public iTextPdf(string path)
        {
            _path = path;
        }

        public void SavePdf(List<iTextPdf> pdflist,string savefile)
        {
            using (Stream inputPdfStream = new FileStream(_path, FileMode.Open, FileAccess.Read, FileShare.Read))   //打开pdf模板
            using (Stream outputPdfStream = new FileStream(savefile, FileMode.Create, FileAccess.Write, FileShare.None))    //创建新的pdf对象用于保存
            {
                var reader = new PdfReader(inputPdfStream);
                var stamper = new PdfStamper(reader, outputPdfStream);
                var list = pdflist.OrderBy(x => x.PageIndex);   //对页号运行排序
                //FontFactory.RegisterDirectory("C:\WINDOWS\Fonts");  //字体目录
                list.Select(x => x.PageIndex).Distinct().ToList().ForEach(page =>
                {   //先按页进行遍历,可以减少实例化pdfContentByte的次数,减少资源占用
                    var pdfContentByte = stamper.GetOverContent(page);
                    Rectangle pagesize = reader.GetPageSizeWithRotation(page);
                    float height = pagesize.Height;
                    list.Where(x => x.PageIndex.Equals(page)).ToList().ForEach(item =>
                    { //针对每页进行要插入的内容进行遍历
                        switch (item.Type)
                        {
                            case 1:
                            case 2:
                                string content = item.Content;
                                float fontsize = 12;    //字号
                                if (!string.IsNullOrEmpty(content))
                                {   //只处理有文字内容的
                                    if ((2).Equals(item.Type))
                                    {   //对勾选的内容进行处理
                                        if ("1".Equals(content))
                                        {   //标记为1的,内容换成√,按插入文字处理
                                            content = "√"; 
                                            fontsize = 16;
                                        }
                                        else
                                        {
                                            content = "";
                                            break;
                                        }

                                    }
                                    BaseFont bfTimes = BaseFont.CreateFont(System.Web.HttpContext.Current.Request.MapPath("~/fonts/simhei.ttf"), BaseFont.IDENTITY_H, BaseFont.EMBEDDED);   //注册字体,支持中文
                                    pdfContentByte.SetColorFill(BaseColor.BLACK);

                                    pdfContentByte.SetFontAndSize(bfTimes, fontsize);   //设置字体及字号
                                    pdfContentByte.BeginText(); //开始处理文字
                                    pdfContentByte.ShowTextAligned(Element.ALIGN_LEFT, content, item.X, height - item.Y, 0);
                                    pdfContentByte.EndText();   //文字处理达成
                                }

                                break;
                            case 4:
                            case 5:  //身份证图片
                                string imgpath = System.Web.HttpContext.Current.Request.MapPath(item.Content);  //图片物理路径
                                using (Stream inputImageStream = new FileStream(imgpath, FileMode.Open, FileAccess.Read, FileShare.Read))   //打开图片
                                {
                                    Image image = Image.GetInstance(inputImageStream);
                                    image.SetAbsolutePosition(item.X, item.Y);  //图片坐标
                                    image.ScaleAbsolute(item.Width, item.Height);   //设置图片宽度和高度
                                    pdfContentByte.AddImage(image);
                                }
                                break;
                        }
                    });
                });

                stamper.Close();    //关闭同时保存
            }
        }
    }
}

本文作者:老徐

本文链接:https://cloud.tencent.com/developer/article/1405656

转载时须注明出处及本声明

0 人点赞