利用ItextSharp产PDF完整操作

摘要:
记得上回有写到用C#操作Excel很多朋友说推荐用NPOI,的确,用微软自带的操作execl会有很大的问题。客户的主机不愿意安装excel,这时我才意识到用自带组件完全是不行的,我本来准备改用NPOI组件,但是这时客户提出为了安全,改用后台产PDF。

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

很多朋友说推荐用NPOI,的确,用微软自带的操作execl会有很大的问题。客户的主机不愿意安装excel,
这时我才意识到用自带组件完全是不行的,我本来准备改用NPOI组件,但是这时客户提出为了安全(数据安全),改用后台产PDF。
这就有了本文中ITextSharp的用法
本文介绍了基本全套的用法,包括页眉,页首,表格的用法,但是还是有很多问题没有处理好,只是把我已经ok的地方拿出来给一些需要的朋友学习。
一:下载地址
下面这篇博文说明了ITextsharp的下载地址,本人就是按照这篇文章进行的下载
http://www.cnblogs.com/haogj/archive/2011/09/05/2167659.html
注意版本不同,一些函数的用法也不相同了
二:产出PDF
/// <summary>
        ///产生PDf
        /// </summary>
        /// <param name="strFileName">文件名称</param>
        /// <param name="dt">数据源</param>
        public void PDF(string strFileName, DataTable dt, stringPrintName)
        {
            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 = newFileStream(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 = newPdfPTable(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, stringPrintName)
        {
            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 = newPdfPCell(phshead);
            pchead.VerticalAlignment = 1;
            pchead.HorizontalAlignment = 1;
            PdfPCell pcjimi = newPdfPCell(phsjimi);
            PdfPCell pcPeople = newPdfPCell(phsPeople);
            PdfPCell pcPage = newPdfPCell(phsPage);
            PdfPCell pcPrintDate = newPdfPCell(phsPrintDate);
            PdfPCell pcnull = newPdfPCell();
            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 = newPhrase();
            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);
            returnphead;

        }
页尾的方法
/// <summary>
        ///页尾
        /// </summary>
        /// <returns></returns>
        publicHeaderFooter Foot()
        {
            string strFoot = @"XXXXXXXXXXXXXXXXXX";
            Phrase pfoot = new Phrase(strFoot, PdfFont.Font(2));
            HeaderFooter foot = new HeaderFooter(pfoot, false);
            foot.Border =Rectangle.NO_BORDER;
            returnfoot;
        }
3:字体的问题 如果没有定义字体,汉字是不会出现的,下面是我定义的字体,使用的ITextSharp控件字体,当然也可以使用字体文件详情可查看http://winsystem.ctocio.com.cn/334/12194834.shtml
/// <summary>
        ///文字类型定义
        /// </summary>
        /// <param name="IType">返回文字类别</param>
        /// <returns></returns>
        public static Font Font(intIType)
        {
            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: returnfont;
                case 2: returnfontFoot;
                case 3: returnfontNormal;
                default: returnfontNormal;
            }
        }

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, stringstrName)
        {
            PdfReader pdfReader = null;
            PdfStamper pdfStamper = null;
            try{
                pdfReader = newPdfReader(inputfilepath);

                int numberOfPages =pdfReader.NumberOfPages;

                iTextSharp.text.Rectangle psize = pdfReader.GetPageSize(1);

                float width =psize.Width;

                float height =psize.Height;

                pdfStamper = new PdfStamper(pdfReader, newFileStream(outputfilepath, FileMode.Create));

                PdfContentByte waterMarkContent;

                WatermarkCreater wmc = newWatermarkCreater();
                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,方法相同至此可以达到客户的要求,但是一些样式的问题就需要大家仔细研究了,这就是我的实践过程,希望可以和大家一起学习了

免责声明:文章转载自《利用ItextSharp产PDF完整操作》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇说说微软MVC中Model用法mysql分组取每组前几条记录(排名)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

CVE

一、简介 CVE 的英文全称是“Common Vulnerabilities & Exposures”公共漏洞和暴露。CVE就好像是一个字典表,为广泛认同的信息安全漏洞或者已经暴露出来的弱点给出一个公共的名称。使用一个共同的名字,可以帮助用户在各自独立的各种漏洞数据库中和漏洞评估工具中共享数据,虽然这些工具很难整合在一起。这样就使得CVE成为了安全...

HTTP.SYS远程代码执行漏洞测试(ms15-034)

1.HTTP.SYS远程代码执行漏洞简介 首先漏洞编号:CVE-2015-1635(MS15-034 ) 远程执行代码漏洞存在于 HTTP 协议堆栈 (HTTP.sys) 中,当 HTTP.sys 未正确分析经特殊设计的 HTTP 请求时会导致此漏洞。 成功利用此漏洞的攻击者可以在系统帐户的上下文中执行任意代码。 利用HTTP.sys的安全漏洞,攻击者只需...

如何写出安全的API接口(参数加密+超时处理+私钥验证+Https)

原文:http://www.cnblogs.com/codeon/p/6123863.html#3580351 1.完全开放的接口 有没有这样的接口,谁都可以调用,谁都可以访问,不受时间空间限制,只要能连上互联网就能调用,毫无安全可言。 实话说,这样的接口我们天天都在接触,你查快递,你查天气预报,你查飞机,火车班次等,这些都是有公共的接口。 我把这称之为裸...

移动App该如何保存用户密码(转)

原文地址:http://blog.csdn.net/hengyunabc/article/details/34623957 移动App该如何保存用户密码? 这个实际上和桌面程序是一样的。 先看下一些软件是如何保存用户密码的: 我们先来看下QQ是怎么保存密码的: 参考:http://bbs.pediy.com/archive/index.php?t-159...

Windows 11和 Linux 漏洞赋予攻击者最高系统权限

微软的 Windows 10 和即将推出的 Windows 11 版本被发现存在一个新的本地提权漏洞,该漏洞允许具有低级别权限的用户访问 Windows 系统文件,进而使他们能够揭开操作系统安装密码的掩码,甚至解密私钥. CERT 协调中心 (CERT/CC) 在周一发布的漏洞说明中表示:“从 Windows 10 build 1809 开始,非管理用户...

js判断浏览器类型

js判断浏览器类型 <script type="text/javascript" ><!-- function getOs() { var OsObject = ""; if(isIE = navigator.userAgent.indexOf("MSIE")!=-1) { return "MSIE"; } if(isFirefox=na...