我正在尝试调整pdf文档的大小,然后在每页中放置一个图章。
我正在使用“文档”调整大小,并使用“ PdfStamper”作为图章。
PdfStamper stamp = new PdfStamper(reader, output);
Document document = new Document();
问题是当我关闭两次时:document.close()和stamp.close() 我收到 ExceptionConverter:java.io.IOException:流已关闭
我知道这是因为我同时关闭了文档和图章,但是如果我只关闭了一个,则仅关闭对象即可。
我不知道该如何处理。
有什么想法吗? 谢谢!
编辑-这是我现在拥有的所有代码:
public void generateReducedPdf() throws Exception {
//lectura del pdf a copiar
PdfReader reader = new PdfReader("C:/Users/X30261GE/Downloads/ES_O00012741_2018_000000000000000000000000000153.pdf");
int numberOfPages = reader.getNumberOfPages();
Document document = new Document();
//creación del nuevo pdf, junto con su ruta y nombre.
FileOutputStream output = new FileOutputStream("C:/Users/X30261GE/Downloads/pdfReducido.pdf");
PdfWriter writer = PdfWriter.getInstance(document, output);
//PDF TIPO PDF/A1-b
writer.setPDFXConformance(com.lowagie.text.pdf.PdfWriter.PDFA1B);
document.open();
document.setPageSize(PageSize.A4);
PdfDictionary outi = new PdfDictionary(PdfName.OUTPUTINTENT);
outi.put(PdfName.OUTPUTCONDITIONIDENTIFIER, new PdfString("sRGB IEC61966-2.1"));
outi.put(PdfName.INFO, new PdfString("sRGB IEC61966-2.1"));
outi.put(PdfName.S, PdfName.GTS_PDFA1);
InputStream inst = ActionSignPdf.class.getClassLoader().getResourceAsStream("resources/sRGB.profile");
com.itextpdf.text.pdf.ICC_Profile icc = ICC_Profile.getInstance(inst);
PdfICCBased ib = new PdfICCBased(icc);
ib.remove(PdfName.ALTERNATE);
outi.put(PdfName.DESTOUTPUTPROFILE, writer.addToBody(ib).getIndirectReference());
writer.getExtraCatalog().put(PdfName.OUTPUTINTENTS, new PdfArray(outi));
PdfContentByte pdfContent = writer.getDirectContent();
for (int i = 1; i <= numberOfPages; i++) {
document.newPage();
PdfImportedPage page = writer.getImportedPage(reader, i);
// Reducir las paginas al 80%
pdfContent.addTemplate(page, .85f, 0, 0, .85f, 70, 110);
}
writer.createXmpMetadata();
document.close();
writer.close();
//AHORA StAMP time
//PRUEBA DE STAMP AQUI
PdfStamper stamp = new PdfStamper(reader, output);
PdfContentByte over;
FontFactory.defaultEmbedding = true;
FontFactory.register(ActionSignPdf.class.getResource("").getPath() + "Helvetica.ttf", ActionSignPdf.class.getResource("").getPath() + "Helvetica.ttf");
BaseFont bf = BaseFont.createFont(ActionSignPdf.class.getResource("").getPath() + "Helvetica.ttf", BaseFont.WINANSI, BaseFont.EMBEDDED);
BaseFont bfNegrita = BaseFont.createFont(BaseFont.TIMES_BOLD, BaseFont.WINANSI, BaseFont.EMBEDDED);
// mete el for
for (int i = 1; i <= numberOfPages; i++) {
//PRUEBA DEL StAMP AQUI
over = stamp.getOverContent(i);
over.beginText();
//set fuente negrita
over.setFontAndSize(bfNegrita,8);
//Primera linea
//Coloco la primera parte en negrita
int posLineaXNegrita = 150;
over.showTextAligned(0, RegistroKeys.KEY_DIRECCION , posLineaXNegrita, 50, 0);
//segunda parte
//set fuente sin negrita
over.setFontAndSize(bf,7);
//posicion x donde colocare la segunda parte sin negrita
int posLineaX = RegistroKeys.KEY_DIRECCION.length() + posLineaXNegrita + 108;
over.setLineWidth(0);
over.showTextAligned(0, RegistroKeys.KEY_DIRECCION_URL , posLineaX, 50, 0);
//Siguiente linea
//set fuente negrita
over.setFontAndSize(bfNegrita,8);
//primera parte en negrita
posLineaXNegrita = 200;
over.showTextAligned(Element.ALIGN_CENTER, RegistroKeys.KEY_CODIGO_SEGURO_DESCARGA, posLineaXNegrita, 40, 0);
//segunda parte
//set fuente sin negrita
over.setFontAndSize(bf,7);
//posicion x donde colocare la segunda parte sin negrita
posLineaX = RegistroKeys.KEY_CODIGO_SEGURO_DESCARGA.length() + posLineaXNegrita + 105;
String codigo = "#002#9B4ECE66-A34D-3C0A-A6FA-6D67C31C9550";
over.showTextAligned(Element.ALIGN_CENTER, codigo, posLineaX, 40, 0);
over.endText();
over.stroke();
}
stamp.close();
}
就像您在评论中说的那样,我正在尝试在同一PDF中使用图章和文档,但这将无法正常工作。
我必须先处理文档,然后再处理压模。 有任何想法吗?谢谢!
答案 0 :(得分:0)
在评论中发现,实际问题是
我认为我首先要处理文档,然后使用该结果来使用Stamper。现在我的问题是,该怎么做,如何从文档生成的输出中获取字节数组。
您可以通过将Document
/ PdfWriter
对写到ByteArrayOutputStream
来实现:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, baos);
...
document.close();
...
PdfReader intermediary = new PdfReader(baos.toByteArray());
PdfStamper stamp = new PdfStamper(intermediary, output);
...
stamp.close();
您的类路径中似乎有多个iText版本,尤其是您同时使用了com.lowagie.text.pdf
和com.itextpdf.text.pdf
包中的两个类,即5.x版本和版本4.2、2.x或更低版本。
混合使用不同的iText版本可能会产生最奇怪的效果。我建议您从类路径中删除所有较旧的版本,并且仅使用最新的5.x。当您称自己为iText中的菜鸟时,您甚至应该考虑切换到iText 7.x,除非您现有的基于iText 5的代码库太大而无法维护。
您仅使用Document
/ Writer
对来复制PdfReader reader
中的页面并设置一些PDF / A标记。为此,您应该考虑使用Document
/ PdfCopy
对,甚至使用PdfStamper
。您的解决方案将丢弃所有动态PDF结构(注释,...)和所有文档级数据(元数据,...)。
顺便说一下,PDF / A不仅仅是一些文档设置,这是源PDF必须已经满足的许多前提条件,否则您的输出将无法通过PDF / A验证。