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;
        }

    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章