java itext7 生成pdf及电子签章及加背景图片
1. 除了引入itext7 的相關jar包以外,還需要相關jar包:bcpkix-jdk15to18-163.jar,bcprov-jdk15to18-163.jar?(這兩個一定要有,不然會報錯,其他包看情況而定,參考鏈接里面JDK 1.5 - JDK 1.8)
2. 生成 .keystore 文件
? ?參考:https://blog.csdn.net/u014386474/article/details/51996019?&?https://blog.csdn.net/devil_bye/article/details/82759140
3. 1)把生成好的 keystore文件放入某個固定目錄下面,我放到了D:\\cert\\下面
? ? 2)把bcprov-jdk15to18-163.jar文件放入 jdk/jre/lib/ext 目錄下面
? ? 3) 配置安全屬性文件,在 jdk/jre/lib/security 目錄下有個 java.security 文件,如看到:
? ? ? ? ?security.provider.1=sun.security.provider.Sun
security.provider.2=sun.security.rsa.SunRsaSign
? ? ? ? 插入新的提供者:
? ? ? ? ?security.provider.3=org.bouncycastle.jce.provider.BouncyCastleProvider
如果不配置這一步,會報java.security.NoSuchProviderException: no such provider: BC 這個問題(應該是)
?
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import com.itextpdf.io.image.ImageData;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.colors.DeviceRgb;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.xobject.PdfImageXObject;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Div;
import com.itextpdf.layout.element.Image;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.property.BackgroundImage;
import com.itextpdf.layout.property.Property;
import com.itextpdf.layout.property.TextAlignment;
import com.itextpdf.layout.property.UnitValue;
import com.itextpdf.signatures.BouncyCastleDigest;
import com.itextpdf.signatures.IExternalDigest;
import com.itextpdf.signatures.IExternalSignature;
import com.itextpdf.signatures.PdfSignatureAppearance;
import com.itextpdf.signatures.PdfSignatureAppearance.RenderingMode;
import com.itextpdf.signatures.PdfSigner;
import com.itextpdf.signatures.PdfSigner.CryptoStandard;
import com.itextpdf.signatures.PrivateKeySignature;
public class PDFUtil {
?? ?
?? ?private static final String destFolder = System.getProperty("user.dir");
?? ?
?? ?public static final String KEYSTORE = "D:\\cert\\xxx.keystore";
? ? public static final char[] PASSWORD = "linyutang".toCharArray();//keystory密碼
? ? private static String stamperSrc = "D:\\cert\\stamper.png";
?? ?public PDFUtil() {
?? ??? ?
?? ?}
?? ?
?? ?public static void createPdf(String fileName, String exportDate, List<String> headList,
?? ??? ??? ?List<String> fieldList, List<Map<String, Object>> dataList, HttpServletResponse response) {
?? ??? ?
?? ??? ?try {
?? ??? ??? ?
//?? ??? ??? ?File destFile = new File(destFolder + "\\" + fileName);
//?? ??? ??? ?
//?? ??? ??? ?if (!destFile.exists()) {
//?? ??? ??? ??? ?destFile.createNewFile();
//?? ??? ??? ?}
?? ??? ??? ?PdfDocument pdfDoc = new PdfDocument(/* new PdfWriter(destFile) */ new PdfWriter(response.getOutputStream()));
?? ??? ??? ?Document doc = new Document(pdfDoc);
?? ??? ??? ?
?? ??? ??? ?response.reset();
?? ??? ??? ?response.setContentType("application/pdf");
?? ??? ??? ?response.setHeader("Content-Disposition", "attachment; filename=" + fileName);//要保存的文件名
?? ??? ??? ?response.setContentType("application/octet-stream; charset=gbk");
?? ??? ??? ?
?? ??? ??? ?
?? ??? ??? ?Div div = new Div();
?? ??? ??? ?
?? ??? ??? ?PdfFont sysFont = PdfFontFactory.createFont("STSongStd-Light", "UniGB-UCS2-H", false);
?? ??? ??? ?Paragraph paragraph = new Paragraph();
?? ??? ??? ?paragraph.add("學習記錄-" + exportDate).setFont(sysFont).setBold().setFontSize(20).setTextAlignment(TextAlignment.CENTER);
?? ??? ??? ?div.add(paragraph);
?? ??? ??? ?
?? ??? ??? ?div.add(new Paragraph(""));
?? ??? ??? ?
?? ??? ??? ?Table dataTable = new Table(headList.size()).setWidth(UnitValue.createPercentValue(100));
?? ??? ??? ?for (int i = 0; i < headList.size(); i++) {
?? ??? ??? ??? ?String headTitle = headList.get(i);
?? ??? ??? ??? ?dataTable.addCell(new Cell().add(new Paragraph(headTitle)).setFont(sysFont)
?? ??? ??? ??? ??? ??? ?.setBackgroundColor(new DeviceRgb(221, 234, 238)));
?? ??? ??? ?}
?? ??? ??? ?
?? ??? ??? ?for (int i = 0; i < dataList.size(); i++) {
?? ??? ??? ??? ?Map<String, Object> dataMap = dataList.get(i);
?? ??? ??? ??? ?
?? ??? ??? ??? ?for (int j = 0; j < fieldList.size(); j++) {
?? ??? ??? ??? ??? ?String mapKeyVal = fieldList.get(j);
?? ??? ??? ??? ??? ?
?? ??? ??? ??? ??? ?String value = dataMap.get(mapKeyVal).toString();
?? ??? ??? ??? ??? ?
?? ??? ??? ??? ??? ?dataTable.addCell(new Cell().add(new Paragraph(value).setFont(sysFont)));
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ??? ?
?? ??? ??? ?PdfImageXObject imageXObject = new PdfImageXObject(ImageDataFactory.create(stamperSrc));
? ? ? ? ? ? BackgroundImage backgroundImage = new BackgroundImage(imageXObject);
?? ??? ??? ?div.add(dataTable);
?? ??? ??? ?div.setProperty(Property.BACKGROUND_IMAGE, backgroundImage);
?? ??? ??? ?doc.add(div);
?? ??? ??? ?
?? ??? ??? ?pdfDoc.close();
?? ??? ??? ?
//?? ??? ??? ?KeyStore ks;
//?? ??? ??? ?try {
//?? ??? ??? ??? ?ks = KeyStore.getInstance("jks");
//?? ??? ??? ??? ?ks.load(new FileInputStream(KEYSTORE), PASSWORD);
//?? ? ? ? ? ? ? ?String alias = (String) ks.aliases().nextElement();
//?? ? ? ? ? ? ? ?PrivateKey pk = (PrivateKey) ks.getKey(alias, PASSWORD);
//?? ? ? ? ? ? ? ?Certificate[] chain = ks.getCertificateChain(alias);
//?? ? ? ? ? ? ? ?
//?? ? ? ? ? ? ? ?String preSrc = "";
//?? ? ? ? ? ? ? ?String fileNum = "";
//?? ? ? ? ? ? ? ?
//?? ? ? ? ? ? ? ?System.out.println("----numberOfPages == " + pdfDoc.getNumberOfPages());
//?? ? ? ? ? ? ? ?
//?? ? ? ? ? ? ? ?for (int i=1; i<=pdfDoc.getNumberOfPages(); i++) {
//?? ? ? ? ? ? ? ??? ?if (i - 1 == 0) {
//?? ? ? ? ? ? ? ??? ??? ?fileNum = "";
//?? ? ? ? ? ? ? ??? ?} else {
//?? ? ? ? ? ? ? ??? ??? ?fileNum = (i - 1) + "";
//?? ? ? ? ? ? ? ??? ?}
//?? ? ? ? ? ? ? ??? ?String src = "D:\\itext\\20190926_study_record_list" + fileNum + ".pdf";
//?? ? ? ? ? ? ? ??? ?String dest = "D:\\itext\\20190926_study_record_list" + i + ".pdf";
//?? ? ? ? ? ? ? ??? ?sign(src, "Signature" + i, ?dest, chain, pk, DigestAlgorithms.SHA256, null, CryptoStandard.CADES, "Test " + i,
//?? ??? ? ? ? ? ? ? ? ? ? ? ?"Ghent", i);
//?? ? ? ? ? ? ? ??? ?preSrc = src;
//?? ? ? ? ? ? ? ?}
//?? ? ? ? ? ? ? ?
//?? ??? ??? ?} catch (KeyStoreException e) {
//?? ??? ??? ??? ?// TODO Auto-generated catch block
//?? ??? ??? ??? ?e.printStackTrace();
//?? ??? ??? ?} catch (NoSuchAlgorithmException e) {
//?? ??? ??? ??? ?// TODO Auto-generated catch block
//?? ??? ??? ??? ?e.printStackTrace();
//?? ??? ??? ?} catch (CertificateException e) {
//?? ??? ??? ??? ?// TODO Auto-generated catch block
//?? ??? ??? ??? ?e.printStackTrace();
//?? ??? ??? ?} catch (UnrecoverableKeyException e) {
//?? ??? ??? ??? ?// TODO Auto-generated catch block
//?? ??? ??? ??? ?e.printStackTrace();
//?? ??? ??? ?} catch (GeneralSecurityException e) {
//?? ??? ??? ??? ?// TODO Auto-generated catch block
//?? ??? ??? ??? ?e.printStackTrace();
//?? ??? ??? ?}
? ? ? ? ? ??
?? ??? ??? ?
?? ??? ??? ?doc.close();
?? ??? ??? ?
?? ??? ?} catch (FileNotFoundException e) {
?? ??? ??? ?e.printStackTrace();
?? ??? ?} catch (IOException e) {
?? ??? ??? ?e.printStackTrace();
?? ??? ?}
?? ?}
?? ?
?? ?public static void sign(String src, ?//需要簽章的pdf文件路徑
?? ??? ??? ? String name,
? ? ? ? ? ? ?String dest, ?// 簽完章的pdf文件路徑
? ? ? ? ? ? ?Certificate[] chain, //證書鏈
? ? ? ? ? ? ?PrivateKey pk, //簽名私鑰
? ? ? ? ? ? ?String digestAlgorithm, ?//摘要算法名稱,例如SHA-1
? ? ? ? ? ? ?String provider, ?// 密鑰算法提供者,可以為null
? ? ? ? ? ? ?CryptoStandard subfilter, //數字簽名格式,itext有2種
? ? ? ? ? ? ?String reason, ?//簽名的原因,顯示在pdf簽名屬性中,隨便填
? ? ? ? ? ? ?String location,?
? ? ? ? ? ? ?int pageNum) //簽名的地點,顯示在pdf簽名屬性中,隨便填
? ? ? ? ? ? ?throws GeneralSecurityException, IOException {
? ? ? ? //下邊的步驟都是固定的,照著寫就行了,沒啥要解釋的
? ? ? ? PdfReader reader = new PdfReader(src);
? ? ? ? //目標文件輸出流
? ? ? ? FileOutputStream os = new FileOutputStream(dest);
? ? ? ??
? ? ? ? System.out.println("src == " + src + ", dest == " + dest);
? ? ? ??
? ? ? ? //創建簽章工具PdfSigner ,最后一個boolean參數?
? ? ? ? //false的話,pdf文件只允許被簽名一次,多次簽名,最后一次有效
? ? ? ? //true的話,pdf可以被追加簽名,驗簽工具可以識別出每次簽名之后文檔是否被修改
? ? ? ? PdfSigner stamper = new PdfSigner(reader, os, true);
? ? ? ??
? ? ? ? stamper.setFieldName(name);
? ? ? ??
? ? ? ? // 獲取數字簽章屬性對象,設定數字簽章的屬性
? ? ? ? PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
? ? ? ? appearance.setReason(reason);
? ? ? ? appearance.setLocation(location);
? ? ? ? ImageData img = ImageDataFactory.create(stamperSrc);
? ? ? ? //讀取圖章圖片,這個image是itext包的image
? ? ? ? Image image = new Image(img);
? ? ? ? float height = image.getImageHeight();
? ? ? ? float width = image.getImageWidth();
? ? ? ? //設置簽名的位置,頁碼,簽名域名稱,多次追加簽名的時候,簽名與名稱不能一樣
? ? ? ? //簽名的位置,是圖章相對于pdf頁面的位置坐標,原點為pdf頁面左下角
? ? ? ? //四個參數的分別是,圖章左下角x,圖章左下角y,圖章寬度,圖章高度
? ? ? ? appearance.setPageNumber(pageNum);
? ? ? ? appearance.setPageRect(new Rectangle(250, 100, width / 2, height / 2));
? ? ? ? //插入蓋章圖片
? ? ? ? appearance.setSignatureGraphic(img);?
? ? ? ? //設置圖章的顯示方式,如下選擇的是只顯示圖章(還有其他的模式,可以圖章和簽名描述一同顯示)
? ? ? ? appearance.setRenderingMode(RenderingMode.GRAPHIC);
? ? ? ? // 這里的itext提供了2個用于簽名的接口,可以自己實現,后邊著重說這個實現
? ? ? ? // 摘要算法
? ? ? ? IExternalDigest digest = new BouncyCastleDigest();
? ? ? ? // 簽名算法
? ? ? ? IExternalSignature signature = new PrivateKeySignature(pk, digestAlgorithm, BouncyCastleProvider.PROVIDER_NAME);
? ? ? ? // 調用itext簽名方法完成pdf簽章
? ? ? ? stamper.setCertificationLevel(1);
? ? ? ? stamper.signDetached(digest,signature, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
}
?? ?
}
參考:https://www.cnblogs.com/bumblebee-xy/p/7291265.html
總結
以上是生活随笔為你收集整理的java itext7 生成pdf及电子签章及加背景图片的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 操作系统概述以及启动、中断和系统调用
- 下一篇: uni-app接入环信客服云 easem