c#用iTextSharp生成pdf文档

c#用iTextSharp生成pdf文档

在应用中有时需要生成pdf文档。在vs中用nuget添加 iTextSharp的引用,就可以方便的操作pdf了

先上一段常用操作的代码

using iTextSharp.text.pdf;
using System.IO;
using iTextSharp.text;

namespace Net.BLL.Pdf
{
    /// <summary>
    /// PDF文档操作类
    /// </summary>
    //------------------调用--------------------------
    //PDFOperation pdf = new PDFOperation();
    //pdf.Open(filepath); 或 pdf.Open(new FileStream(pdfNewFile, FileMode.Create));
    //pdf.SetBaseFont(@"C:\Windows\Fonts\SIMHEI.TTF");
    //pdf.AddParagraph("测试文档(生成时间:" + DateTime.Now + ")", 15, 1, 20, 0, 0);
    //pdf.Close();
    //-------------------------------
    public class PDFOperation
    {
        #region 构造函数
        /// <summary>
        /// 构造函数,默认A4大小
        /// </summary>
        public PDFOperation()
        {
            rect = PageSize.A4;
            document = new Document(rect);
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="type">页面大小(如"A4")可选值A1-A10,B1,B2等 参考PageSize的值</param>
        public PDFOperation(string type)
        {
            SetPageSize(type);
            document = new Document(rect);
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="type">页面大小(如"A4") 可选值A1-A10,B1,B2等 参考PageSize的值</param>
        /// <param name="marginLeft">内容距左边框距离</param>
        /// <param name="marginRight">内容距右边框距离</param>
        /// <param name="marginTop">内容距上边框距离</param>
        /// <param name="marginBottom">内容距下边框距离</param>
        public PDFOperation(string type, float marginLeft, float marginRight, float marginTop, float marginBottom)
        {
            SetPageSize(type);
            document = new Document(rect, marginLeft, marginRight, marginTop, marginBottom);
        }
        #endregion

        #region 私有字段
        private Font font;
        private Rectangle rect;  //文档大小
        private Document document;//文档对象
        private BaseFont basefont;//字体
        private PdfWriter pdfWriter; 
        #endregion

        #region 设置字体
        /// <summary>
        /// 设置字体 D:\\Windows\\Fonts\\SIMSUN.TTC 如该字体,没有可以从网上下载后放在系统字体文件夹下
        /// 不设置的话默认字体不支持中文
        /// </summary>
        public void SetBaseFont(string path)
        {
            basefont = BaseFont.CreateFont(path, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        }

        /// <summary>
        /// 设置字体
        /// </summary>
        /// <param name="size">字体大小</param>
        public void SetFont(float size)
        {
            font = new Font(basefont, size);
        }
        #endregion

        #region 设置页面大小
        /// <summary>
        /// 设置页面大小
        /// </summary>
        /// <param name="type">页面大小(如"A4") 可选值A1-A10,B1,B2等 参考PageSize的值</param>
        public void SetPageSize(string type)
        {
            switch (type.Trim())
            {
                case "A4":
                    rect = PageSize.A4;
                    break;
                case "A8":
                    rect = PageSize.A8;
                    break;
            }
        }
        #endregion

        #region 实例化文档
        /// <summary>
        /// 实例化文档
        /// </summary>
        /// <param name="os">文档相关信息(如路径,打开方式等)</param>
        public void GetInstance(Stream os)
        {
            pdfWriter = PdfWriter.GetInstance(document, os);
        }
        #endregion

        #region 打开文档对象
        /// <summary>
        /// 打开文档对象
        /// </summary>
        /// <param name="os">文档相关信息(如路径,打开方式等)</param>
        public void Open(Stream os)
        {
            GetInstance(os);
            document.Open();
        }

        /// <summary>
        /// 打开文档对象
        /// </summary>
        /// <param name="pdfNewFile">文档路径</param>
        public void Open(string pdfNewFile)
        {
            pdfWriter = PdfWriter.GetInstance(document, new FileStream(pdfNewFile, FileMode.Create));
            document.Open();
        }
        #endregion

        #region 关闭打开的文档
        /// <summary>
        /// 关闭打开的文档
        /// </summary>
        public void Close()
        {
            document.Close();
            pdfWriter.Close();
        }
        #endregion

        #region 添加段落
        /// <summary>
        /// 添加段落
        /// </summary>
        /// <param name="contents">内容</param>
        /// <param name="fontsize">字体大小</param>
        public void AddParagraph(string contents, float fontsize)
        {
            SetFont(fontsize);
            Paragraph pra = new Paragraph(contents, font);
            document.Add(pra);
        }

        /// <summary>
        /// 添加段落,文本段
        /// </summary>
        /// <param name="contents">内容</param>
        /// <param name="fontsize">字体大小</param>
        /// <param name="Alignment">对齐方式(1为居中,0为居左,2为居右)</param>
        /// <param name="SpacingAfter">段后空行数(0为默认值)</param>
        /// <param name="SpacingBefore">段前空行数(0为默认值)</param>
        /// <param name="MultipliedLeading">行间距(0为默认值)</param>
        public void AddParagraph(string contents, float fontsize, int Alignment, float SpacingAfter, float SpacingBefore, float MultipliedLeading)
        {
            SetFont(fontsize);
            Paragraph pra = new Paragraph(contents, font);
            pra.Alignment = Alignment;
            if (SpacingAfter != 0)
            {
                pra.SpacingAfter = SpacingAfter;
            }
            if (SpacingBefore != 0)
            {
                pra.SpacingBefore = SpacingBefore;
            }
            if (MultipliedLeading != 0)
            {
                pra.MultipliedLeading = MultipliedLeading;
            }
            document.Add(pra);
        }

        #endregion

        #region 添加图片
        /// <summary>
        /// 添加图片
        /// </summary>
        /// <param name="path">图片路径</param>
        /// <param name="Alignment">对齐方式(1为居中,0为居左,2为居右)</param>
        /// <param name="newWidth">图片宽(0为默认值,如果宽度大于页宽将按比率缩放)</param>
        /// <param name="newHeight">图片高</param>
        public void AddImage(string path, int Alignment, float newWidth, float newHeight)
        {
            Image img = Image.GetInstance(path);
            img.Alignment = Alignment;
            if (newWidth != 0)
            {
                img.ScaleAbsolute(newWidth, newHeight);
            }
            else
            {
                if (img.Width > PageSize.A4.Width)
                {
                    img.ScaleAbsolute(rect.Width, img.Width * img.Height / rect.Height);
                }
            }
            document.Add(img);
        }
        #endregion

        #region 添加链接、点
        /// <summary>
        /// 添加链接
        /// </summary>
        /// <param name="Content">链接文字</param>
        /// <param name="FontSize">字体大小</param>
        /// <param name="Reference">链接地址</param>
        public void AddAnchorReference(string Content, float FontSize, string Reference)
        {
            SetFont(FontSize);
            Anchor auc = new Anchor(Content, font);
            auc.Reference = Reference;
            document.Add(auc);
        }
        /// <summary>
        /// 添加链接点
        /// </summary>
        /// <param name="Content">链接文字</param>
        /// <param name="FontSize">字体大小</param>
        /// <param name="Name">链接点名</param>
        public void AddAnchorName(string Content, float FontSize, string Name)
        {
            SetFont(FontSize);
            Anchor auc = new Anchor(Content, font);
            auc.Name = Name;
            document.Add(auc);
        }
        #endregion

        #region === 其它属性设置 ===
        /// <summary>
        /// 设置title
        /// </summary>
        /// <param name="title"></param>
        public void SetTitle(string title)
        {
            document.AddTitle(title);
        }

        /// <summary>
        /// 设置subject
        /// </summary>
        /// <param name="subject"></param>
        public void SetSubject(string subject)
        {
            document.AddSubject(subject);
        }

        /// <summary>
        /// 设置keywords
        /// </summary>
        /// <param name="keywords"></param>
        public void SetKeywords(string keywords)
        {
            document.AddKeywords(keywords);
        }

        /// <summary>
        /// 设置creator
        /// </summary>
        /// <param name="creator"></param>
        public void SetCreator(string creator)
        {
            document.AddCreator(creator);
        }

        /// <summary>
        /// 设置author
        /// </summary>
        /// <param name="author"></param>
        public void SetAuthor(string author)
        {
            document.AddAuthor(author);
        }
        #endregion
    }
}

如何调用代码中详细的说明,但是你会发现,操作pdf文档过程中添加文本,添加图片这些常见的方法都没有问题,但最终生成出来的文档却差强人意

原因在哪?当然是排版的问题,要调整好文本段落与图片的布局,位置很是麻烦。虽然iTextSharp支持图片,文本的插入位置设置,但用代码来设置还是很费劲。

最好的方式就是先做好pdf文档的模板,利用模板来生成想要的pdf文档,这样省时省力,但前提就是模板文件要准备好。

模板文件可以利用pdf编辑器生成,你可以考虑用Adobe Acrobat DC系列的工具来做,做文档的过程中最重要的就是在文档中添加好对应的表单,在代码中分别在对应的表单域名中添加对应的元素。这样的话,位置,样式统统可以在模板文档中设置中,代码中只管添加元素进去。

下面是利用模板来生成pdf文档的代码

using System;
using System.Collections.Generic;
using iTextSharp.text.pdf;
using System.IO;
using iTextSharp.text;



namespace Net.BLL.Pdf
{
    /// <summary>
    /// 使用pdf模板方式创建pdf的帮助类
    /// </summary>
    //------- 调用示例 --------
    //  Net.BLL.Pdf.PdfWithTemplateHelper pdf = new Net.BLL.Pdf.PdfWithTemplateHelper();
    //  pdf.Open("E:\\PdfTest\\mytemplate.pdf", "E:\\PdfTest\\test.pdf");
    //  pdf.PutText("txttitle", "pdf生成测试");
    //  pdf.PutText("txtuser001", "Me \r\n生日:1988-8-9 \r\n爱好:运动、健身、旅游");
    //  pdf.PutImage(1, "img001", "e:/PdfTest/pic01.jpg");
    //  pdf.PutText("txtuser002", "肖鼠:鼠年出生的人的本命佛是千手观音,得千手观音庇佑。肖鼠的人财运好,在十二生肖中属于富贵型!");
    //  pdf.PutImage(1, "img002", "e:/PdfTest/pic02.jpg");
    //  pdf.PutText("txtbuddha001", "生命在于运动!人生不止,运动不息!");
    //  pdf.Close();
    //--------- end -----------
    public class PdfWithTemplateHelper
    {
        PdfReader pdfReader = null;
        PdfStamper pdfStamper = null;
        AcroFields pdfFormFields = null;
        PdfWriter pdfWriter = null;

        public PdfWithTemplateHelper()
        {

        }

        /// <summary>
        /// 创建文档
        /// </summary>
        /// <param name="pdfTemplateFile">模板文件路径</param>
        /// <param name="pdfNewFile">要生成的文档路径</param>
        public void Open(string pdfTemplateFile, string pdfNewFile)
        {
            pdfReader = new PdfReader(pdfTemplateFile);
            pdfStamper = new PdfStamper(pdfReader, new FileStream(pdfNewFile, FileMode.OpenOrCreate));
            pdfFormFields = pdfStamper.AcroFields;
            pdfStamper.FormFlattening = true;
        }
        
        /// <summary>
        /// 关闭并保存文档
        /// </summary>
        public void Close()
        {
            pdfStamper.Close();
            pdfReader.Close();

            pdfStamper = null;
            pdfReader = null;
            pdfFormFields = null;
        }

        /// <summary>
        /// 批量添加图片
        /// </summary>
        /// <param name="pageIndex">页码</param>
        /// <param name="fieldName">表单域名称</param>
        /// <param name="imageFile">图片文件</param>
        /// <param name="rowCount"></param>
        /// <param name="colCount"></param>
        /// <param name="space"></param>
        /// <param name="isScale">是否按比例缩放</param>
        /// <param name="isSquare">是否正方形</param>
        /// <returns></returns>
        public bool PutImageMatrix(int pageIndex, string fieldName, List<string> imageFile, int rowCount, int colCount, int space = 5, bool isScale = true, bool isSquare = false)
        {

            PdfContentByte pdfContentByte = pdfStamper.GetOverContent(pageIndex);
            if (pdfContentByte == null)
            {
                return false;
            }

            var positions = pdfFormFields.GetFieldPositions(fieldName);
            if (positions.Count == 0)
            {
                return false;
            }

            AcroFields.FieldPosition fieldPosition = positions[0];
            Rectangle rect = fieldPosition.position;

            float left = rect.Left;
            float top = rect.Top;
            float bottom = rect.Bottom;
            float width = rect.Width;
            float height = rect.Height;

            float cellH = (height - space * (rowCount + 1)) / rowCount;
            float cellW = (width - space * (colCount + 1)) / colCount;


            int index = 0;
            for (int row = rowCount - 1; row >= 0; row--)
            {
                float posBotton = bottom + (cellH + space) * row + space;

                for (int col = 0; col < colCount; col++)
                {
                    float posLeft = left + (cellW + space) * col + space;

                    if (index < imageFile.Count)
                    {
                        Image image = Image.GetInstance(imageFile[index]);

                        if (isScale)
                        {
                            image.SetAbsolutePosition(posLeft, posBotton);
                            image.ScaleAbsolute(cellW, cellH);
                        }
                        else
                        {
                            Single imageWidth = image.Width;
                            Single imageHeight = image.Height;

                            if (isSquare)
                            {
                                imageWidth = Math.Min(image.Width, image.Height);
                                imageHeight = Math.Min(image.Width, image.Height);
                            }

                            Rectangle rectDst = new Rectangle(0, 0, 0, 0);
                            rectDst.Left = posLeft;
                            rectDst.Right = posLeft + cellW;
                            rectDst.Bottom = posBotton;
                            rectDst.Top = posBotton + cellH;
                            Rectangle rect1 = GetValidRect(rectDst, imageWidth, imageHeight);
                            image.SetAbsolutePosition(rect1.Left, rect1.Bottom);
                            image.ScaleAbsolute(rect1);
                        }

                        pdfContentByte.AddImage(image);
                    }

                    index++;
                }
            }

            return true;
        }

        /// <summary>
        /// 添加图片
        /// </summary>
        /// <param name="pageIndex">页码</param>
        /// <param name="fieldName">表单域名称</param>
        /// <param name="imageFile">图片文件</param>
        /// <param name="isScale">是否缩放</param>
        /// <returns></returns>
        public bool PutImage(int pageIndex, string fieldName, string imageFile, bool isScale = true)
        {
            PdfContentByte pdfContentByte = pdfStamper.GetOverContent(pageIndex);
            if (pdfContentByte == null)
            {
                return false;
            }

            var positions = pdfFormFields.GetFieldPositions(fieldName);
            if (positions.Count == 0)
            {
                return false;
            }

            AcroFields.FieldPosition fieldPosition = positions[0];
            Rectangle rectDst = fieldPosition.position;

            Image image = Image.GetInstance(imageFile);

            if (isScale)
            {
                image.SetAbsolutePosition(rectDst.Left, rectDst.Bottom);
                image.ScaleAbsolute(rectDst);
            }
            else
            {
                Single imageWidth = image.Width;
                Single imageHeight = image.Height;
                Rectangle rect = GetValidRect(rectDst, imageWidth, imageHeight);
                image.SetAbsolutePosition(rect.Left, rect.Bottom);
                image.ScaleAbsolute(rect);
            }

            pdfContentByte.AddImage(image);

            return true;
        }

        /// <summary>
        /// 添加文本内容
        /// </summary>
        /// <param name="fieldName">表单域名称</param>
        /// <param name="str">文本内容</param>
        /// <returns></returns>
        public bool PutText(string fieldName, string str)
        {
            BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
            BaseFont simheiBase = BaseFont.CreateFont("D:\\Windows\\Fonts\\SIMSUN.TTC,1", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
            pdfFormFields.AddSubstitutionFont(simheiBase);

            pdfFormFields.SetField(fieldName, str);


            return true;
        }


        Rectangle GetValidRect(Rectangle rectDst, Single imageWith, Single imageHeight)
        {
            Rectangle rect = new Rectangle(0, 0);

            double dRatio0 = ((double)rectDst.Width) / rectDst.Height;
            double dRatio1 = ((double)imageWith) / imageHeight;
            double ratio = 0;
            if (dRatio1 > dRatio0)
            {
                ratio = ((double)rectDst.Width) / imageWith;
                double realHeight = imageHeight * ratio;

                double diffHeight = (rectDst.Height - realHeight) / 2;
                rect.Left = rectDst.Left;
                rect.Top = (float)(rectDst.Top - diffHeight);
                rect.Right = rectDst.Right;
                rect.Bottom = (float)(rectDst.Bottom + diffHeight);
            }
            else
            {
                ratio = ((double)rectDst.Height) / imageHeight;
                double realWidth = imageWith * ratio;

                double diffWidth = (rectDst.Width - realWidth) / 2;
                rect.Left = (float)(rectDst.Left + diffWidth);
                rect.Top = rectDst.Top;
                rect.Right = (float)(rectDst.Right - diffWidth);
                rect.Bottom = rectDst.Bottom;
            }

            return rect;
        }

    }
}
发布了285 篇原创文章 · 获赞 492 · 访问量 389万+

猜你喜欢

转载自blog.csdn.net/huwei2003/article/details/103288453