zoukankan      html  css  js  c++  java
  • 利用ItextSharp产PDF完整操作

     记得上回有写到用C#操作Excel(.net 4.0)

    很多朋友说推荐用NPOI,的确,用微软自带的操作execl会有很大的问题。客户的主机不愿意安装excel,
    这时我才意识到用自带组件完全是不行的,我本来准备改用NPOI组件,但是这时客户提出为了安全(数据安全),改用后台产PDF。
    这就有了本文中ITextSharp的用法
    本文介绍了基本全套的用法,包括页眉,页首,表格的用法,但是还是有很多问题没有处理好,只是把我已经ok的地方拿出来给一些需要的朋友学习。
     
    一:下载地址
    下面这篇博文说明了ITextsharp的下载地址,本人就是按照这篇文章进行的下载
    注意版本不同,一些函数的用法也不相同了
     
    二:产出PDF
     
     /// <summary>
            /// 产生PDf
            /// </summary>
            /// <param name="strFileName">文件名称</param>
            /// <param name="dt">数据源</param>
            public void PDF(string strFileName, DataTable dt, string PrintName)
            {
                if (!Directory.Exists(AppConfigString.FilePath))
                {
                    Directory.CreateDirectory(AppConfigString.FilePath);
                }
                string strPathTemp = AppConfigString.FilePath + DateTime.Now.ToString("yyyyMMddhhmmss") + ".pdf";
                //零時的pdf地址,用于水印读取文件
                string strPath = AppConfigString.FilePath + strFileName;//真正文件的位置
                Document document = new Document(PageSize.A4, 25, 25, 25, 25);
                FileStream stream = new FileStream(strPathTemp, FileMode.Create);
                PdfWriter writer = PdfWriter.GetInstance(document, stream);
                document.Footer = Foot();//页尾的函数,在open前定义
                document.Open();
                HeaderFooter head = new HeaderFooter(HeadTable(3, PrintName), true);
                //true为在页眉的右边生成一个页数,会影响到页眉的高度,在open后定义
                //headTable为页眉的函数
                head.Border = Rectangle.NO_BORDER;
                document.Header = head;
                //页眉第一页不会出现,第2页才会出现,所以此地直接在第一列加了一个表头
                //页尾在第一页就会出现
                document.Add(HeadTable(3, PrintName));//第一頁表頭不自動添加
                //主要数据的添加
                int IRowCount = dt.Rows.Count;
                int IColumnCount = dt.Columns.Count;
                PdfPTable pdfTb = new PdfPTable(IColumnCount);
                pdfTb.HeaderRows = 1;//自動加表頭
                for (int i = 0; i < IRowCount; i++)
                {
                    for (int j = 0; j < IColumnCount; j++)
                    {
                        string value = dt.Rows[i][j].ToString();
                        Phrase phs = new Phrase(value, PdfFont.Font(3));
                        //此时把数据转为Phrase只是为了使用字体,不然中文不能显示
                        pdfTb.AddCell(phs);
                    }
                }
                document.Add(pdfTb);
                document.Close();
                writer.Close();
                PDFWatermark(strPathTemp, strPath, 10, 10, PrintName);//为生成好的文件添加水印
    
            }
     上面为一段完整的使用过程,注释是我刚加的,比较详细了,说下面几个问题  1:页眉和页首    》页眉与页首都使用相同的类HeaderFooter,只是页眉是给 document.Header,页尾是给document.Footer    》页尾是在document.open前,页眉是在document.open后    》页眉第一页不会出现,第2页才会出现,所以此地直接在第一列加了一个表头。页尾在第一页就会出现。  2:页眉的制作方法   由于页眉不好制作,所以我选择直接先拼成PdfPTable,再把PdfPTable放到Phrase,再把Phrase放到HeaderFooter给页眉,这样就好操作些   这个是在百度知道上找到的思路,我就这样做了,呵呵...  下面为我制作页眉的方法,一些信息安全问题已换为XXXXX 
    /// <summary>
            /// 產生表頭的數據
            /// </summary>
            /// <param name="IType">1:ID 2:Name 3:detali</param>
            /// <returns></returns>
            public Phrase HeadTable(int IType, string PrintName)
            {
                string strhead = "";
                switch (IType)
                {
                    case 1: strhead = "XXXXXXXXXXXXXXXXXXXX"; break;
                    case 2: strhead = "XXXXXXXXXXXXXXXXXXXX"; break;
                    case 3: strhead = "XXXXXXXXXXXXXXXXXXXX"; break;
                }
                Phrase phshead = new Phrase(strhead, PdfFont.Font(1));
                Phrase phsjimi = new Phrase("XXXXXXXXXXXXXXXXXXXX ", PdfFont.Font(3));
    
                Phrase phsPeople = new Phrase("XXXXXXXXXXXXXXXXXXXX" + PrintName + "XXXXXXXXXXXXXXXXXXXX" + PrintName, PdfFont.Font(3));
                Phrase phsPage = new Phrase(" ", PdfFont.Font(3));
                Phrase phsPrintDate = new Phrase("列印時間:" + DateTime.Now.ToString("yyyy/MM/dd hh:mm") + "
     Print Date:" + DateTime.Now.ToString("yyyy/MM/dd hh:mm"), PdfFont.Font(3));
                PdfPCell pchead = new PdfPCell(phshead);
                pchead.VerticalAlignment = 1;
                pchead.HorizontalAlignment = 1;
                PdfPCell pcjimi = new PdfPCell(phsjimi);
                PdfPCell pcPeople = new PdfPCell(phsPeople);
                PdfPCell pcPage = new PdfPCell(phsPage);
                PdfPCell pcPrintDate = new PdfPCell(phsPrintDate);
                PdfPCell pcnull = new PdfPCell();
                pchead.Border = 0;
                pcjimi.Border = 0;
                pcPeople.Border = 0;
                pcPage.Border = 0;
                pcPrintDate.Border = 0;
                pcnull.Border = 0;
                pcPeople.PaddingBottom = 10;
                pcPrintDate.PaddingBottom = 10;
                Phrase phead = new Phrase();
                PdfPTable thead = new PdfPTable(2);
                thead.AddCell(pchead);
                thead.AddCell(pcjimi);
                thead.AddCell(pcnull);
                thead.AddCell(pcPage);
                thead.AddCell(pcPeople);
                thead.AddCell(pcPrintDate);
                thead.SetWidths(new float[] { PageSize.A4.Width, 200 });
                phead.Add(thead);
                return phead;
    
            }
     
     
     页尾的方法
            /// <summary>
            /// 页尾
            /// </summary>
            /// <returns></returns>
            public HeaderFooter Foot()
            {
                string strFoot = @"XXXXXXXXXXXXXXXXXX";
                Phrase pfoot = new Phrase(strFoot, PdfFont.Font(2));
                HeaderFooter foot = new HeaderFooter(pfoot, false);
                foot.Border = Rectangle.NO_BORDER;
                return foot;
            }
     3:字体的问题  如果没有定义字体,汉字是不会出现的,下面是我定义的字体,使用的ITextSharp控件字体,当然也可以使用字体文件详情可查看http://winsystem.ctocio.com.cn/334/12194834.shtml 
            /// <summary>
            /// 文字类型定义
            /// </summary>
            /// <param name="IType">返回文字类别</param>
            /// <returns></returns>
            public static Font Font(int IType)
            {
                BaseFont.AddToResourceSearch("iTextAsian.dll");
                BaseFont.AddToResourceSearch("iTextAsianCmaps.dll");
                BaseFont bf = BaseFont.CreateFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
                //简体?繁体不能使用
                //
                Font font = new Font(bf);//普通文章
                font.Size = 10;
                Font fontFoot = new Font(bf);//頁脚文字
                fontFoot.Size = 7;
                fontFoot.Color = Color.RED;
                Font fontNormal = new Font(bf);//正常文字
                fontNormal.Size = 7;
                switch (IType)
                {
                    case 1: return font;
                    case 2: return fontFoot;
                    case 3: return fontNormal;
                    default: return fontNormal;
                }
            }
     
    4:主要内容的制作 根据数据源,利用PdfPTable和Phase等制作,块等我还没用会,主要是样式和定位没搞会下面的博客有在Asp.Net中操作PDF – iTextSharp -利用块,短语,段落添加文本的方法http://www.cnblogs.com/CareySon/archive/2011/11/03/2234625.html5:水印的添加
            /// <summary>
            /// 為生成的pdf添加水印
            /// </summary>
            /// <param name="inputfilepath"></param>
            /// <param name="outputfilepath"></param>
            /// <param name="top"></param>
            /// <param name="left"></param>
            /// <returns></returns>
            public bool PDFWatermark(string inputfilepath, string outputfilepath, float top, float left, string strName)
            {
                PdfReader pdfReader = null;
                PdfStamper pdfStamper = null;
                try
                {
                    pdfReader = new PdfReader(inputfilepath);
    
                    int numberOfPages = pdfReader.NumberOfPages;
    
                    iTextSharp.text.Rectangle psize = pdfReader.GetPageSize(1);
    
                    float width = psize.Width;
    
                    float height = psize.Height;
    
                    pdfStamper = new PdfStamper(pdfReader, new FileStream(outputfilepath, FileMode.Create));
    
                    PdfContentByte waterMarkContent;
    
                    WatermarkCreater wmc = new WatermarkCreater();
                    Draw.Image image = wmc.GetImageByte(strName, AppConfigString.WaterMarkPath);
                    var img = Image.GetInstance(image, System.Drawing.Imaging.ImageFormat.Png);
                    if (left < 0)
                    {
                        left = width - image.Width + left;
                    }
                    img.SetAbsolutePosition(left, (height - image.Height) - top);
                    //每一页加水印,也可以设置某一页加水印 
                    for (int i = 1; i <= numberOfPages; i++)
                    {
                        waterMarkContent = pdfStamper.GetUnderContent(i);
    
                        waterMarkContent.AddImage(img);
                    }
                    return true;
                }
                catch (Exception ex)
                {
                    ex.Message.Trim();
                    return false;
                }
                finally
                {
    
                    if (pdfStamper != null)
                        pdfStamper.Close();
    
                    if (pdfReader != null)
                        pdfReader.Close();
                    //把添加水印前的pdf文件刪除,保存最新的文件
                    if (File.Exists(inputfilepath))
                    {
                        File.Delete(inputfilepath);
                    }
                }
    
            }
    这就是我们为什么要用一个零时路径了,先把产出的pdf放到零时路径,用来产生水印的时候读取,生成水印文件后,再把零时文件删除即可其中的WatermarkCreater方法可以看我以前的博客,报表水印的产生http://www.cnblogs.com/xiaoshuai1992/p/waterMark.html,方法相同 至此可以达到客户的要求,但是一些样式的问题就需要大家仔细研究了,这就是我的实践过程,希望可以和大家一起学习了
  • 相关阅读:
    redis学习(四)
    redis学习(三)
    redis学习(二)
    redis学习(一)
    Maven入门(二)pom.xml和核心概念
    Maven入门(一)
    uni-app 引用
    uni-app 搜索栏
    Vue,组件切换-切换动画
    Vue,组件切换-方式2
  • 原文地址:https://www.cnblogs.com/xiaoshuai1992/p/itextsharp.html
Copyright © 2011-2022 走看看