用iText替换BIRT生成的报告中的单个图像
我正在使用BIRT生成一个带有PDF输出的简单报告。这个文档有一些空白(用带有特定颜色的占位符图像填充,作为嵌入图像插入BIRT),我想用用户提供的图像替换这些空白 BIRT在封面下使用iText,所以我决定在第5版中也使用iText。该文档如下所示: 现在,我编写这段代码是为了填补第一个缺口:用iText替换BIRT生成的报告中的单个图像,itext,birt,Itext,Birt,我正在使用BIRT生成一个带有PDF输出的简单报告。这个文档有一些空白(用带有特定颜色的占位符图像填充,作为嵌入图像插入BIRT),我想用用户提供的图像替换这些空白 BIRT在封面下使用iText,所以我决定在第5版中也使用iText。该文档如下所示: 现在,我编写这段代码是为了填补第一个缺口: private void replaceStream(PRStream orig, PdfStream stream) throws IOException { orig.clear();
private 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));
}
}
private void placeSignature(File source, File target, File signature)
throws IOException, DocumentException {
PdfReader reader = new PdfReader(source.getPath());
PdfObject obj;
for (int i = 1; i <= reader.getXrefSize(); i++) {
obj = reader.getPdfObject(i);
if (obj != null && obj.isStream()) {
PRStream stream = (PRStream) obj;
byte[] b;
try {
b = PdfReader.getStreamBytes(stream);
} catch (UnsupportedPdfException e) {
b = PdfReader.getStreamBytesRaw(stream);
}
BufferedImage img = ImageIO.read(new ByteArrayInputStream(b));
if (img != null) {
boolean signaturePlaceholder = true;
for (int x = 0; x < img.getWidth(); x++) {
for (int y = 0; y < img.getHeight(); y++) {
// Check if image is a placeholder, matches a colour
if (img.getRGB(x, y) != -65) {
signaturePlaceholder = false;
}
}
}
if (signaturePlaceholder) {
Image img2 = Image.getInstance(signature.getPath());
PdfImage newImg = new PdfImage(img2, "", null);
replaceStream(stream, newImg);
System.out.println("Replaced!");
break;
}
}
}
}
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(target));
stamper.close();
reader.close();
}
@Test
public void testReplace() throws IOException, DocumentException {
placeSignature(new File("src/test/resources/signature_test2.pdf"),
new File("target/signature_test2.pdf"),
new File("src/test/resources/signature.jpg"));
}
private void replaceStream(PRStream orig,PdfStream stream)引发IOException{
原始清除();
ByteArrayOutputStream bas=新的ByteArrayOutputStream();
stream.writeContent(baos);
原始setData(baos.toByteArray(),false);
对于(PdfName名称:stream.getKeys()){
原始put(name,stream.get(name));
}
}
私有void placeSignature(文件源、文件目标、文件签名)
抛出IOException,DocumentException{
PdfReader reader=新的PdfReader(source.getPath());
PdfObject-obj;
对于(int i=1;i,PDF中的页面仅包含一个单独的图像XObject资源,该资源在一个单独的表单XObject资源中使用,该资源在页面内容流中使用了三次
因此,在您替换了唯一的图像资源之后,页面上的所有(间接)用法都会显示替换图像
如果要使用iText更改此设置,则必须编辑内容流,并使用新图像替换XObject使用的表单指令。但首先必须确定哪些XObject使用是要替换的
非常重要,特别是如果Birt模板具有一定的灵活性
我建议您使用不同的图像(使用不同的标记颜色)对于报表模板中的不同位置。这当然会变得越来越困难,因为此类占位符图像越多,尤其是如果数字是动态的,并且可能会变得任意大,例如,在具有未知但可能大量条目的数据集中,每个数据集条目一个。我在这里有点幸运,不是吗有动态占位符,不要期望它们也是动态的。不同标记颜色的想法似乎也很有价值,但是在我的测试中,我对图像的顺序没有问题,只要我为每个间隙提供不同的图像。无论如何,谢谢你澄清我在PDF中的内容,因为我是解析的初学者!