前言:
由于项目中使用jdk版本为1.6没有办法,本来已经使用itext7实现了参数替换和图片逻辑,被迫使用itext5再实现一次,列出实现逻辑希望能帮到大家:当然如果jdk是1.8及以上,那么还是建议大家使用itext7进行实现,因为官网主打就是itext7相关说明、文档只会,使用起来也比itext5简单些。
说以下自己的需求:处理纯英文协议(处理中文需要添加相关字体),需要动态给协议中某些页输入客户的信息和图片手写签名图片;然后将pdf上传至oss上。
主要工作量在摸索参数替换和签名图片替换上,其他的细节比如,中文转英文,姓名转拼音(因为姓名通过中转英,例如,高进翻译成high enter就尴尬了)有第三方和支持的jar,这里就不说这些。
添加以下相关的包:
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.9</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-pdfa</artifactId>
<version>5.5.9</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-xtra</artifactId>
<version>5.5.9</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.9</version>
</dependency>
1.替换参数代码
public class ReplaceStream {
public static final String SRC = "resources/pdfs/hello.pdf";
public static final String DEST = "results/stamper/hello_changed.pdf";
public static void main(String[] args) throws IOException, DocumentException {
File file = new File(DEST);
file.getParentFile().mkdirs();
new ReplaceStream().manipulatePdf(SRC, DEST);
}
public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
PdfReader reader = new PdfReader(src);
PdfDictionary dict = reader.getPageN(1);
PdfObject object = dict.getDirectObject(PdfName.CONTENTS);
if (object instanceof PRStream) {
PRStream stream = (PRStream)object;
byte[] data = PdfReader.getStreamBytes(stream);
stream.setData(new String(data).replace("Hello World", "HELLO WORLD").getBytes());
}
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
stamper.close();
reader.close();
}
}
2.图片替换代码
public class ReplaceImage {
public static final String SRC = "resources/pdfs/image.pdf";
public static final String DEST = "results/images/image_replaced.pdf";
public static void main(String[] args) throws DocumentException, IOException {
File file = new File(DEST);
file.getParentFile().mkdirs();
new ReplaceImage().manipulatePdf(SRC, DEST);
}
public void manipulatePdf(String src, String dest) throws DocumentException, IOException {
PdfReader reader = new PdfReader(src);
PdfDictionary page = reader.getPageN(1);
PdfDictionary resources = page.getAsDict(PdfName.RESOURCES);
PdfDictionary xobjects = resources.getAsDict(PdfName.XOBJECT);
//itext5添加的图片元素为/FXX开头不一定为第一个,因此取最后一个,itext7就没有这个困扰
PdfName imgRef = (PdfName) xObjects.getKeys().toArray()[xObjects.getKeys().size()-1];
PRStream stream = (PRStream) xObjects.getAsStream(imgRef);
PdfImage image = new PdfImage(makeBlackAndWhitePng(new PdfImageObject(stream)), "", null);
replaceStream(stream, image);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
stamper.close();
reader.close();
}
public static Image makeBlackAndWhitePng(PdfImageObject image) throws IOException, DocumentException {
BufferedImage bi = image.getBufferedImage();
BufferedImage newBi = new BufferedImage(bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_USHORT_GRAY);
newBi.getGraphics().drawImage(bi, 0, 0, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(newBi, "png", baos);
return Image.getInstance(baos.toByteArray());
}
public static void replaceStream(PRStream orig, PdfStream stream) throws IOException {
orig.clear();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
stream.writeContent(baos);
orig.setData(baos.toByteArray(), false);
for (PdfName name : stream.getKeys()) {
orig.put(name, stream.get(name));
}
}
}
以上粘贴的代码主要来自itext官网,参数替换可以直接使用,图片替换作了一些修改,避免替换失败情况。
以上就是替换参数和图片替换的核心代码,有任何问题请及时留言。