1 环境及背景
SpringBoot项目,使用poi、itextpdf将excel、ppt、word文件转为pdf,并对pdf文件进行签章;
对Excel文件加图片水印,并加密设置为只读。
下面的方法都是返回的byte数组,可视具体情况直接将文件输出。
office文件分为2003跟2007版本,所以处理的方法回有所区别。
还有很多其他方式可以实现转pdf,例如可以用第三方插件aspose处理office文件,但是需要收费;
可以使用spire,也是收费的;
还可以使用OpenOffice办公组件,加org.jodconverter,组件是适用于Linux,windows的。
2 pdf文件加盖签章
数字证书生成:
keytool -storepass 123456 -genkeypair -keyalg RSA -keysize 1024 -sigalg SHA1withRSA -validity 3650 -alias mycert -keystore my.keystore -dname "CN=www.sample.com, OU=sample, O=sample, L=BJ, ST=BJ, C=CN"
打开cmd窗口直接执行上面命令即可,会生成一个 my.keystore的文件。
/**
* 对pdf进行签章
* @param src pdf文件输入流
* @param imgPath 签章图片路径
* @param reason 签章原因
* @param location 签章地点
* @return
* @throws GeneralSecurityException
* @throws IOException
* @throws DocumentException
*/
public static byte[] sign(InputStream src,String imgPath,String reason,String location) throws GeneralSecurityException, IOException, DocumentException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] resBytes = null;
try{
//读取keystore ,获得私钥和证书链
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(ConvertImgToBase64Util.loadImgResource("templates/keystore/keystore.p12"),"123456".toCharArray());
String alias = (String)keyStore.aliases().nextElement();
PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, "123456".toCharArray());
Certificate[] chain = keyStore.getCertificateChain(alias);
PdfReader pdfReader = new PdfReader(src);
Rectangle rectangle= pdfReader.getPageSize(1);
float urx = rectangle.getRight()-100;
float ury = rectangle.getTop()-100;
float llx = urx-200;
float lly = ury-200;
PdfStamper stamper = PdfStamper.createSignature(pdfReader, baos, '', null, false);
// 获取数字签章属性对象,设定数字签章的属性
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
appearance.setReason(reason);
appearance.setLocation(location);
appearance.setVisibleSignature(new Rectangle(llx,lly,urx,ury), 1, "sign");
//获取盖章图片
byte[] imgBytes = ConvertImgToBase64Util.image2Bytes(imgPath);
Image image = Image.getInstance(imgBytes);
appearance.setSignatureGraphic(image);
//设置认证等级
appearance.setCertificationLevel(PdfSignatureAppearance.NOT_CERTIFIED);
//印章的渲染方式,这里选择只显示印章
appearance.setRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC);
ExternalDigest digest = new BouncyCastleDigest();
//签名算法,参数依次为:证书秘钥、摘要算法名称,例如MD5 | SHA-1 | SHA-2.... 以及 提供者
ExternalSignature signature = new PrivateKeySignature(PrivateKey, DigestAlgorithms.SHA1, null);
//调用itext签名方法完成pdf签章
MakeSignature.signDetached(appearance, digest, signature, chain, null, null, null, 0,MakeSignature.CryptoStandard.CMS);
resBytes = baos.toByteArray();
}catch (Exception e){
log.error("pdf文件签章异常:{}",e);
}finally {
try{
if(baos != null){
baos.close();
}
}catch (IOException e){
log.error("关闭io流异常:{}",e);
}
}
return resBytes;
}
上面代码出现的keystore.p12就是my.keystore
3 word转pdf
3.1 docx转pdf
public static byte[] docxToPdf(InputStream src) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] resBytes = null;
String result;
try {
// pdf文件的尺寸
Document pdfDocument = new Document(PageSize.A3, 72, 72, 72, 72);
PdfWriter pdfWriter = PdfWriter.getInstance(pdfDocument, baos);
XWPFDocument doc = new XWPFDocument(src);
pdfWriter.setInitialLeading(20);
java.util.List<XWPFParagraph> plist = doc.getParagraphs();
pdfWriter