• C# -- ITextSharp生成带水印的PDF


       上周按需求需要在系统上实现PDF带水印文档的导出,网上搜了一下发现开源的组件还挺多的,用的比较多的是ITextsharp,Demo也相对较多,就它了!

       (一)首先下载ITextSharp.dll,可在官网上下载:http://sourceforge.net/projects/itextsharp/,本人用了itextsharp-dll-core文件夹下的dll。

       (二)网上有很多类似的Demo和ITextSharp各属性的详细讲解,就不做重复累赘了,可自行百度参考。

       (三)使用过程:在需要的地方调用CreatePDF.Instance.GeneratePDF()即可,详细代码如下:

      1 //要用到的命名空间
      2     using System.IO;
      3     using iTextSharp.text;
      4     using iTextSharp.text.pdf;
      5     using System.Text;
      6     using System.Data;
      7     public class CreatePDF
      8     {
      9         private static CreatePDF instance;
     10         public static CreatePDF GetInstance()
     11         {
     12             if (instance == null)
     13             {
     14                 instance = new CreatePDF();
     15             }
     16             return instance;
     17         }
     18 
     19         private static Document doc;
     20         private static BaseFont bf = BaseFont.CreateFont(@"C://Windows/Fonts/simsun.ttc,0", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
     21         //四种字体
     22         private static Font fontBig = new Font(bf, 20, Font.BOLD);
     23         private static Font fontMiddle = new Font(bf, 15, Font.BOLD);
     24         private static Font fontSmall = new Font(bf, 13, Font.BOLD);
     25         private static Font fontSmallNoBold = new Font(bf, 13);
     26         private static float IndentationLeft = 50;//距左边距
     27         //如果要传参数进来,可自定义
     28         public void GeneratePDF()
     29         {
     30             doc = new Document(PageSize.A4);
     31             try
     32             {
     33                 //MemoryStream ms2 = new MemoryStream();
     34                 string fileName = string.Format("数据_{0}.pdf", DateTime.Now.ToString("yyyyMMddHHmmss"));
     35                 string filePath = string.Format("{0}/Resource/{1}", AppDomain.CurrentDomain.BaseDirectory, fileName);
     36                 FileStream fs = new FileStream(filePath, FileMode.Create);//创建临时文件,到时生成好后删除
     37                 PdfWriter writer = PdfWriter.GetInstance(doc, fs);
     38                 writer.CloseStream = false;//把doc内容写入流中
     39                 doc.Open();
     40 
     41                 //核心操作
     42                 CreateLine();//生成一条下横线
     43                 CreateEmptyRow(1);//生成一行空行
     44                 AddHeaderTitleContent("表10 已安装工程量明细表");//添加表头
     45                 CreateEmptyRow(1);//生成一行空行
     46                 AddPartnerContent("工程名称", "建设名称", "施工名称", "监理名称");//添加合作单位
     47                 AddPageNumberContent();//添加页码
     48                 CreateEmptyRow(1);//生成一行空行
     49 
     50                 #region 生成表格数据
     51                 PdfPTable table = new PdfPTable(6);//6列的table
     52                 //添加表格列头               
     53                 table.SetTotalWidth(new float[] { 50, 200, 60, 60, 100, 100 });
     54                 table.AddCell(GetPdfCell("序号", fontSmallNoBold, Element.ALIGN_CENTER));
     55                 table.AddCell(GetPdfCell("工程量名称", fontSmallNoBold, Element.ALIGN_CENTER));
     56                 table.AddCell(GetPdfCell("单位", fontSmallNoBold, Element.ALIGN_CENTER));
     57                 table.AddCell(GetPdfCell("数量", fontSmallNoBold, Element.ALIGN_CENTER));
     58                 table.AddCell(GetPdfCell("安装地点、路段", fontSmallNoBold, Element.ALIGN_CENTER));
     59                 table.AddCell(GetPdfCell("备注", fontSmallNoBold, Element.ALIGN_CENTER));
     60 
     61                 int emptyRow = 20;//如果table的行数小于20行,那么剩余部分显示空白行
     62                 #region 构造数据源
     63                 DataTable tableSource = new DataTable();
     64                 tableSource.Columns.Add(new DataColumn("aa"));
     65                 tableSource.Columns.Add(new DataColumn("bb"));
     66                 tableSource.Columns.Add(new DataColumn("cc"));
     67                 tableSource.Columns.Add(new DataColumn("dd"));
     68                 tableSource.Columns.Add(new DataColumn("ee"));
     69                 for (int i = 0; i < 15; i++)
     70                 {
     71                     DataRow row = tableSource.NewRow();
     72                     row["aa"] = "aa";
     73                     row["bb"] = "bb";
     74                     row["cc"] = "cc";
     75                     row["dd"] = "dd";
     76                     row["ee"] = "ee";
     77                     tableSource.Rows.Add(row);
     78                 }
     79                 #endregion
     80                 if (tableSource.Rows.Count > 0)
     81                 {
     82                     emptyRow = emptyRow - tableSource.Rows.Count;//如果为负数,说明不需要生成空白行
     83                     for (int i = 0; i < tableSource.Rows.Count; i++)
     84                     {
     85                         DataRow row = tableSource.Rows[i];
     86                         table.AddCell(GetPdfCell((i + 1).ToString(), fontSmallNoBold, Element.ALIGN_CENTER));
     87                         table.AddCell(GetPdfCell(row["aa"].ToString(), fontSmallNoBold, Element.ALIGN_CENTER));
     88                         table.AddCell(GetPdfCell(row["bb"].ToString(), fontSmallNoBold, Element.ALIGN_CENTER));
     89                         table.AddCell(GetPdfCell(row["cc"].ToString(), fontSmallNoBold, Element.ALIGN_CENTER));
     90                         table.AddCell(GetPdfCell(row["dd"].ToString(), fontSmallNoBold, Element.ALIGN_CENTER));
     91                         table.AddCell(GetPdfCell(row["ee"].ToString(), fontSmallNoBold, Element.ALIGN_CENTER));
     92                     }
     93                 }
     94                 if (emptyRow > 0)//说明数据源不足20行
     95                 {
     96                     for (int i = 0; i < emptyRow; i++)
     97                     {
     98                         table.AddCell(GetPdfCell(((20 - emptyRow) + i + 1).ToString(), fontSmallNoBold, Element.ALIGN_CENTER));
     99                         table.AddCell(GetPdfCell("", fontSmallNoBold, Element.ALIGN_CENTER));
    100                         table.AddCell(GetPdfCell("", fontSmallNoBold, Element.ALIGN_CENTER));
    101                         table.AddCell(GetPdfCell("", fontSmallNoBold, Element.ALIGN_CENTER));
    102                         table.AddCell(GetPdfCell("", fontSmallNoBold, Element.ALIGN_CENTER));
    103                         table.AddCell(GetPdfCell("", fontSmallNoBold, Element.ALIGN_CENTER));
    104                     }
    105                 }
    106                 doc.Add(table); 
    107                 #endregion
    108 
    109                 #region 添加水印
    110                 string waterMarkName = "经度:无  纬度:无  地址:无  验收负责人:无";
    111                 string waterMarkAddr = "广州市天河区";
    112                 if (!string.IsNullOrEmpty(waterMarkAddr))
    113                 {
    114                     waterMarkName = string.Format("经度:{0}  纬度:{1}  地址:{2}  验收负责人:{3}", "113.211", "23.211", waterMarkAddr, "张三");
    115                 } 
    116                 #endregion
    117                 
    118                 doc.Close();
    119                 MemoryStream ms = new MemoryStream();
    120                 if (fs != null)
    121                 {
    122                     byte[] bytes = new byte[fs.Length];//定义一个长度为fs长度的字节数组
    123                     fs.Read(bytes, 0, (int)fs.Length);//把fs的内容读到字节数组中
    124                     ms.Write(bytes, 0, bytes.Length);//把字节内容读到流中
    125                     fs.Flush();
    126                     fs.Close();
    127                 }
    128                 MemoryStream waterMS = SetWaterMark(ms, filePath, waterMarkName);//先生成水印,再删除临时文件
    129                 if (File.Exists(filePath))//判断临时文件是否存在,如果存在则删除
    130                 {
    131                     File.Delete(filePath);
    132                     GC.Collect();//回收垃圾
    133                 }
    134                 SendFile(fileName, waterMS);//把PDF文件发送回浏览器
    135             }
    136             catch (DocumentException ex)
    137             {
    138                 throw new Exception(ex.Message);
    139             }
    140         }
    141         #region 生成一条横线
    142         private static void CreateLine()
    143         {
    144             PdfPTable table = new PdfPTable(1);//一个单元格的
    145             table.TotalWidth = 500;
    146             PdfPCell cell = new PdfPCell();
    147             cell.BorderWidthBottom = 0.5f;
    148             table.AddCell(cell);
    149             doc.Add(table);
    150         }
    151         #endregion
    152 
    153         #region 生成N行空白行
    154         private static void CreateEmptyRow(int emptyRowNum)
    155         {
    156             for (int i = 0; i < emptyRowNum; i++)
    157             {
    158                 doc.Add(new Paragraph(" "));
    159             }
    160         }
    161         #endregion
    162 
    163         #region 生成标题
    164         private static void AddHeaderTitleContent(string content)
    165         {
    166             Paragraph p = new Paragraph(content, fontMiddle);
    167             p.IndentationLeft = IndentationLeft;//距离左边距
    168             doc.Add(p);
    169         }
    170         #endregion
    171 
    172         #region 生成合作单位
    173         private static void AddPartnerContent(string stationName, string constructUnit, string buildUnit, string supervisionUnit)
    174         {
    175             fontMiddle.SetStyle(Font.UNDERLINE);//文字下划线
    176             IndentationLeft = IndentationLeft + 10;
    177 
    178             Paragraph content = new Paragraph();
    179             content.IndentationLeft = IndentationLeft;
    180             Chunk chunkName = new Chunk("单项或单位工程名称:", fontSmallNoBold);
    181             Chunk chunkText = new Chunk(GetEmptyString(25, stationName), fontMiddle);
    182             content.Add(0, chunkName);
    183             content.Add(1, chunkText);
    184             content.Alignment = 3;
    185             doc.Add(content);
    186 
    187             content = new Paragraph();
    188             content.IndentationLeft = IndentationLeft;
    189             chunkName = new Chunk("建设单位名称:", fontSmallNoBold);
    190             chunkText = new Chunk(GetEmptyString(30, constructUnit), fontMiddle);
    191             content.Add(0, chunkName);
    192             content.Add(1, chunkText);
    193             content.Alignment = 3;
    194             doc.Add(content);
    195 
    196             content = new Paragraph();
    197             content.IndentationLeft = IndentationLeft;
    198             chunkName = new Chunk("施工单位名称:", fontSmallNoBold);
    199             chunkText = new Chunk(GetEmptyString(30, buildUnit), fontMiddle);
    200             content.Add(0, chunkName);
    201             content.Add(1, chunkText);
    202             content.Alignment = 3;
    203             doc.Add(content);
    204 
    205             content = new Paragraph();
    206             content.IndentationLeft = IndentationLeft;
    207             chunkName = new Chunk("监理单位名称:", fontSmallNoBold);
    208             chunkText = new Chunk(GetEmptyString(30, supervisionUnit), fontMiddle);
    209             content.Add(0, chunkName);
    210             content.Add(1, chunkText);
    211             content.Alignment = 3;
    212             doc.Add(content);
    213         }
    214         //居中显示内容
    215         private static string GetEmptyString(int maxlength, string text)
    216         {
    217             int padding = (maxlength - text.Length * 2) / 2;
    218             string empty = string.Empty;
    219             for (int i = 0; i < padding; i++)
    220             {
    221                 empty += " ";
    222             }
    223             return string.Format("{0}{1}{0}", empty, text);
    224         }
    225         #endregion
    226 
    227         #region 生成页码
    228         private static void AddPageNumberContent()
    229         {
    230             var content = new Paragraph("共   页  第   页", fontSmall);
    231             content.IndentationRight = IndentationLeft + 20;
    232             content.Alignment = 2;    //居左
    233             doc.Add(content);
    234         }
    235         #endregion
    236 
    237         #region 生成单元格
    238         private static PdfPCell GetPdfCell(string content, Font font, int horizontalAlignment)
    239         {
    240             PdfPCell cell = new PdfPCell(new Paragraph(content, font));
    241             cell.HorizontalAlignment = horizontalAlignment;//水平位置
    242             cell.VerticalAlignment = Element.ALIGN_CENTER;//垂直居中
    243             cell.MinimumHeight = 20;//单元格的最小高度
    244             return cell;
    245         }
    246         #endregion
    247 
    248         #region 生成水印
    249         private static MemoryStream SetWaterMark(MemoryStream ms, string filePath, string waterMarkName, string waterMarkAddr = null)
    250         {
    251             MemoryStream msWater = new MemoryStream();
    252             PdfReader pdfReader = null;
    253             PdfStamper pdfStamper = null;
    254             try
    255             {
    256                 pdfReader = new PdfReader(filePath);
    257                 pdfStamper = new PdfStamper(pdfReader, msWater);
    258 
    259                 int total = pdfReader.NumberOfPages + 1;//获取PDF的总页数
    260                 iTextSharp.text.Rectangle psize = pdfReader.GetPageSize(1);//获取第一页
    261                 float width = psize.Width;//PDF页面的宽度,用于计算水印倾斜
    262                 float height = psize.Height;
    263                 PdfContentByte waterContent;
    264                 BaseFont basefont = BaseFont.CreateFont(@"C:WINDOWSFontsSIMFANG.TTF", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
    265                 PdfGState gs = new PdfGState();
    266                 for (int i = 1; i < total; i++)
    267                 {
    268                     waterContent = pdfStamper.GetOverContent(i);//在内容上方加水印
    269                     //透明度
    270                     waterContent.SetGState(gs);
    271                     //开始写入文本
    272                     waterContent.BeginText();
    273                     waterContent.SetColorFill(BaseColor.RED);
    274                     waterContent.SetFontAndSize(basefont, 18);
    275                     waterContent.SetTextMatrix(0, 0);
    276                     if (waterMarkAddr == null || waterMarkAddr == "")
    277                     {
    278                         waterContent.ShowTextAligned(Element.ALIGN_CENTER, waterMarkName, width / 2, height / 2, 55);
    279                     }
    280                     else
    281                     {
    282                         waterContent.ShowTextAligned(Element.ALIGN_CENTER, waterMarkName, width / 2, height / 2 + 100, 55);
    283                         waterContent.ShowTextAligned(Element.ALIGN_CENTER, waterMarkAddr, width / 2, height / 2 - 100, 55);
    284                     }
    285                     waterContent.EndText();
    286                 }
    287             }
    288             catch (Exception)
    289             {
    290                 return ms;
    291             }
    292             finally
    293             {
    294                 if (pdfStamper != null)
    295                     pdfStamper.Close();
    296 
    297                 if (pdfReader != null)
    298                     pdfReader.Close();
    299             }
    300             return msWater;
    301         }
    302         #endregion
    303 
    304         //-----------------------发送PDF文件回浏览器端----------------------
    305         public static void SendFile(string fileName, MemoryStream ms, Encoding encoding = null)
    306         {
    307             fileName = (fileName + "").Replace(" ", "");
    308             encoding = encoding ?? Encoding.UTF8;
    309             if (ms != null && !string.IsNullOrEmpty(fileName))
    310             {
    311                 System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
    312                 response.Clear();
    313                 response.Charset = encoding.BodyName;// "utf-8";
    314                 if (!HttpContext.Current.Request.UserAgent.Contains("Firefox") && !HttpContext.Current.Request.UserAgent.Contains("Chrome"))
    315                 {
    316                     fileName = HttpUtility.UrlEncode(fileName, encoding);
    317                 }
    318                 response.AddHeader("Content-Disposition", "attachment;filename=" + fileName);
    319                 //为了解决打开,导出NPOI生成的xlsx文件时,提示发现不可读取内容。
    320                 if (!(fileName + "").ToLower().EndsWith(".xlsx"))
    321                 {
    322                     response.AddHeader("Content-Type", "application/octet-stream");
    323                     response.BinaryWrite(ms.GetBuffer());
    324                 }
    325                 else
    326                 {
    327                     response.BinaryWrite(ms.ToArray());
    328                 }
    329                 ms.Close();
    330                 ms = null;
    331                 response.Flush();
    332                 response.End();
    333             }
    334         }
    335     }
    View Code

       (四)总结:

         从代码上,不难看出,普遍用到的标签大多为Document、Paragraph、Table、Cell、Chunck、Font、Element,通过这些标签大概能组合出自己想要的效果,有点类似Html思想。

          a.通过Paragraph、chunck即可显示行元素,若要设置间距或居中等效果,需要熟悉对属性的使用,如设置居中需要Element.ALIGN_CENTER

          b.table操作cell,cell内要添加Paragraph来显示内容,如果需要跨行跨列效果,则可通过cell.Colspan或cell.Rowspan来设置,

          c.实现上不难,如果要达到自己的效果,得多熟悉元素属性的使用和多思考多实践    

         

  • 相关阅读:
    UDP
    TCP
    python基础之socket编程
    单列模式
    元类
    issubclass()和isinstance()
    手持机设备公司(WINCE/ANDROID/LINUX)
    Android Hal 分析
    Android JNI 使用的数据结构JNINativeMethod详解
    MTK GPIO 一些理解
  • 原文地址:https://www.cnblogs.com/jean69/p/6197740.html
Copyright © 2020-2023  润新知