之前这个事情都CA公司去做的,现在给客户做demo,要模拟一下签字盖章了,我们的业务PDF文件是动态生成的所以没法通过坐标定位,只能通过关键字查找定位了。
之前在网上看了许多通多通过查询关键字,然后图片盖章的文章都不完整,说白了基本上没完成。我这边利用了网上查找关键字的方法。
我自己查看了相关Api,然后完善了这个功能。不多说了,直接上代码。
我这个只是示例,默认只取第一个关键字,多个相同关键字,根据业务场景定。 推荐方式:设置白色文字作为关键字,公司的业务我基本上都这样操作。
1.帮助类方法(关键字签字)
1 /// <summary> 2 /// pdf上图片签章 3 /// </summary> 4 public class SealPictureHelper 5 { 6 static float ReSizeMaxWidth = 30; 7 static float ReSizeMaxHeight = 30; 8 /// <summary> 9 /// 手写签字(流和base64格式) 10 /// </summary> 11 /// <param>byte数组的pdf文件</param> 12 /// <param>base64格式的图片</param> 13 /// <param>关键字</param> 14 /// <returns></returns> 15 public static byte[] SignBase64Img(byte[] bytePdf, string SignImgBase64, string SignKeyWord) 16 { 17 byte[] newbytefile; 18 try 19 { 20 using (MemoryStream ms = new MemoryStream()) 21 { 22 // 创建一个PdfReader对象 23 using (PdfReader reader = new PdfReader(bytePdf)) 24 { 25 using (PdfStamper stamper = new PdfStamper(reader, ms)) 26 { 27 // 获得文档页数 28 int n = reader.NumberOfPages; 29 for (int i = 1; i <= n; i++) 30 { 31 //获取当前页 32 PdfContentByte cb = stamper.GetOverContent(i); 33 PdfLocation pz = new PdfLocation(); 34 iTextSharp.text.pdf.parser.PdfReaderContentParser p = new iTextSharp.text.pdf.parser.PdfReaderContentParser(reader); 35 p.ProcessContent<PdfLocation>(i, pz); 36 //查找当前页的关键字 37 pz.SearchKeywords(SignKeyWord); 38 if (pz.TextLocationInfo.Count > 0) 39 { 40 //坐标是从左下角往上,左下角为(0,0)零点 41 XTextInfo o = pz.TextLocationInfo[0]; 42 //获取关键字左上角开始坐标 43 string[] L_T_Location = o.TopLeft.ToString().Split(',');//272.15,766.46,1 44 var left_x = float.Parse(L_T_Location[0]); 45 var top_y = float.Parse(L_T_Location[1]); 46 //获取关键字右下角结束坐标 47 string[] R_B_Location = o.BottomRight.ToString().Split(',');//305.15,755.46,1 48 var right_x = float.Parse(R_B_Location[0]); 49 var bottom_y = float.Parse(R_B_Location[1]); 50 //计算得到关键字的中心点 51 float x = (right_x - left_x) / 2 + left_x; 52 float y = (top_y - bottom_y) / 2 + bottom_y; 53 var imgtest = ConvertBase64ToImage(SignImgBase64); 54 //创建一个图片对象 55 iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(imgtest, System.Drawing.Imaging.ImageFormat.Jpeg); 56 //设置图片的指定大小 57 float expectWidth = img.Width; 58 float expectHeight = img.Height; 59 if (img.Width > img.Height && img.Width > ReSizeMaxWidth) 60 { 61 expectWidth = ReSizeMaxWidth; 62 expectHeight = expectWidth * img.Height / img.Width; 63 } 64 else if (img.Height > img.Width && img.Height > ReSizeMaxHeight) 65 { 66 expectHeight = ReSizeMaxHeight; 67 expectWidth = expectHeight * img.Width / img.Height; 68 } 69 img.ScaleToFit(expectWidth, expectHeight);//img.ScaleToFit(128, 128); 70 //设置图片位置在关键字正中心 71 img.SetAbsolutePosition(x - expectWidth / 2, y - expectHeight / 2);// 72 img.Transparency = new int[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 73 cb.AddImage(img); 74 } 75 } 76 } 77 } 78 newbytefile = ms.ToArray(); 79 } 80 return newbytefile; 81 } 82 catch (Exception ex) 83 { 84 South.Tools.Logger.SaveLogUtil.Error(ex.Message, ex, "SignPicPDF"); 85 return null; 86 } 87 } 88 /// <summary> 89 /// 手写签字(文件路径) 90 /// </summary> 91 /// <param>要签字的pdf文件路径</param> 92 /// <param>签字的图片路径</param> 93 /// <param>关键字</param> 94 /// <returns></returns> 95 public static byte[] SignFile(string Pdf_filePath, string SignImgPath, string SignKeyWord) 96 { 97 byte[] newbytefile; 98 try 99 { 100 using (MemoryStream ms = new MemoryStream()) 101 { 102 // 创建一个PdfReader对象 103 using (PdfReader reader = new PdfReader(Pdf_filePath)) 104 { 105 using (PdfStamper stamper = new PdfStamper(reader, ms)) 106 { 107 // 获得文档页数 108 int n = reader.NumberOfPages; 109 for (int i = 1; i <= n; i++) 110 { 111 //获取当前页 112 PdfContentByte cb = stamper.GetOverContent(i); 113 PdfLocation pz = new PdfLocation(); 114 iTextSharp.text.pdf.parser.PdfReaderContentParser p = new iTextSharp.text.pdf.parser.PdfReaderContentParser(reader); 115 p.ProcessContent<PdfLocation>(i, pz); 116 //查找当前页的关键字 117 pz.SearchKeywords(SignKeyWord); 118 if (pz.TextLocationInfo.Count > 0) 119 { 120 XTextInfo o = pz.TextLocationInfo[0]; 121 //获取关键字左上角开始坐标 122 string[] L_T_Location = o.TopLeft.ToString().Split(',');//272.15,766.46,1 123 var left_x = float.Parse(L_T_Location[0]); 124 var top_y = float.Parse(L_T_Location[1]); 125 //获取关键字右下角结束坐标 126 string[] R_B_Location = o.BottomRight.ToString().Split(',');//305.15,755.46,1 127 var right_x = float.Parse(R_B_Location[0]); 128 var bottom_y = float.Parse(R_B_Location[1]); 129 //计算得到关键字的中心点 130 float x = (right_x - left_x) / 2 + left_x; 131 float y = (top_y - bottom_y) / 2 + bottom_y; 132 //创建一个图片对象 133 iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(SignImgPath); 134 float expectWidth = img.Width; 135 float expectHeight = img.Height; 136 if (img.Width > img.Height && img.Width > ReSizeMaxWidth) 137 { 138 expectWidth = ReSizeMaxWidth; 139 expectHeight = expectWidth * img.Height / img.Width; 140 } 141 else if (img.Height > img.Width && img.Height > ReSizeMaxHeight) 142 { 143 expectHeight = ReSizeMaxHeight; 144 expectWidth = expectHeight * img.Width / img.Height; 145 } 146 //设置图片的指定大小 147 img.ScaleToFit(expectWidth, expectHeight);//img.ScaleToFit(128, 128); 148 //设置图片位置在关键字正中心 149 img.SetAbsolutePosition(x - expectWidth / 2, y - expectHeight / 2);// 150 img.Transparency = new int[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 151 cb.AddImage(img); 152 } 153 } 154 } 155 } 156 newbytefile = ms.ToArray(); 157 } 158 return newbytefile; 159 } 160 catch (Exception ex) 161 { 162 South.Tools.Logger.SaveLogUtil.Error(ex.Message, ex, "SignPicPDF"); 163 return null; 164 } 165 } 166 167 public static System.Drawing.Image ConvertBase64ToImage(string base64String) 168 { 169 byte[] imageBytes = Convert.FromBase64String(base64String); 170 System.Drawing.Bitmap bitmap = null; 171 MemoryStream stream = null; 172 try 173 { 174 stream = new MemoryStream(imageBytes); 175 bitmap = new System.Drawing.Bitmap(stream); 176 //bitmap.Save(IOHelper.getPhysicalDir() + "/test.jpg", System.Drawing.Imaging.ImageFormat.Jpeg); 177 return bitmap; 178 } 179 catch (Exception) 180 { 181 182 throw; 183 } 184 finally 185 { 186 187 //if (stream != null) 188 //{ 189 // stream.Dispose(); 190 //} 191 } 192 193 } 194 }