我试图用itextpdf-5.4.5和itext-pdfa-5.4.5创建一个PDF/A-3.当我设置PdfFileSpecification时,我得到以下异常:
com.itextpdf.text.pdf.PdfAConformanceException: Embedded file shall contain valid Params key.
Run Code Online (Sandbox Code Playgroud)
这是我创建PdfDictionary的部分:
PdfDictionary params = new PdfDictionary();
params.put(PdfName.MODDATE, new PdfDate());
PdfFileSpecification fileSpec = PdfFileSpecification.fileEmbedded(
writer, "./src/main/resources/com/itextpdf/invoice.xml", "invoice.xml", null, false, "text/xml", params);
Run Code Online (Sandbox Code Playgroud)
我找到了检查发生的方法,但我没有找到任何解决方案:
com.itextpdf.text.pdf.internal.PdfA3Checker.checkEmbeddedFile
protected void checkEmbeddedFile(PdfDictionary embeddedFile) {
PdfDictionary params = getDirectDictionary(embeddedFile.get(PdfName.PARAMS));
if (params == null) {
throw new PdfAConformanceException(embeddedFile, MessageLocalization.getComposedMessage("embedded.file.shall.contain.valid.params.key"));
}
Run Code Online (Sandbox Code Playgroud)
任何的想法?先感谢您!
PDF/A-3对嵌入式文件有一些特殊要求,其中包括
嵌入文件的流字典应包含Params键,其值应为至少包含ModDate键的字典,其值应为源文件的最新修改日期.
(ISO 19000-3的附录E.1)
iText支持使用iText解释PDF/A-3如何从头开始创建符合PDF/A-3标准的PDF文件,他们还演示了如何以符合PDF/A-3标准的方式嵌入文件,其示例代码如下:
PdfDictionary parameters = new PdfDictionary();
parameters.put(PdfName.MODDATE, new PdfDate());
PdfFileSpecification fileSpec = PdfFileSpecification.fileEmbedded(
writer, "./src/main/resources/com/itextpdf/invoice.xml",
"invoice.xml", null, "application/xml", parameters, 0);
fileSpec.put(new PdfName("AFRelationship"), new PdfName("Data"));
writer.addFileAttachment("invoice.xml", fileSpec);
PdfArray array = new PdfArray();
array.add(fileSpec.getReference());
writer.getExtraCatalog().put(new PdfName("AF"), array);
Run Code Online (Sandbox Code Playgroud)
此示例还将相关文件条目(AF)添加到目录,这是另一个要求.
顺便说一句,严格来说,Params字典只在一个应该基础上,而不是必须.因此,这实际上是一个建议,并且可以存在有效的PDF/A-3文档,其中包含没有此条目的附件.
因为没有明显的理由为什么iText在创建PDF/A-3文件时不遵循这个建议会更好,但是它的检查的严格解释是可以的.
最近发布了OP发现的检查.在将文件存储在PDF文件中时,已经触发了此检查.不幸的是,此时尚未分配params字典,仅保留了引用.因此,即使在编写字典后不久,检查也会失败.
来自PdfFileSpecification.java
:
stream.put(PdfName.TYPE, PdfName.EMBEDDEDFILE);
stream.flateCompress(compressionLevel);
PdfDictionary param = new PdfDictionary();
if (fileParameter != null) {
param.merge(fileParameter);
}
if (!param.contains(PdfName.MODDATE)) {
param.put(PdfName.MODDATE, new PdfDate());
}
if (fileStore != null) {
param.put(PdfName.SIZE, new PdfNumber(stream.getRawLength()));
stream.put(PdfName.PARAMS, param);
}
else
stream.put(PdfName.PARAMS, refFileLength);
if (mimeType != null)
stream.put(PdfName.SUBTYPE, new PdfName(mimeType));
ref = writer.addToBody(stream).getIndirectReference();
Run Code Online (Sandbox Code Playgroud)
在此操作期间,检查发生(并且失败).
if (fileStore == null) {
stream.writeLength();
param.put(PdfName.SIZE, new PdfNumber(stream.getRawLength()));
writer.addToBody(param, refFileLength);
}
Run Code Online (Sandbox Code Playgroud)
在这之后,直接在这里写下参数.
PdfFileSpecification.fileEmbedded
允许您将数据显示为byte[]
文件系统中的文件而不是文件.正如您在上面的源代码中所看到的,处理在这种情况下有所不同:fileStore
包含该byte[]
参数.如果你fileStore
在那里跟进使用,你会发现,对于null
它的非值,params字典被写为直接对象,因此出现在测试中.
因此,如果您将文件作为byte[]
实例提供,则可以将iText 5.4.5用于PDF/A-3文件附件.
归档时间: |
|
查看次数: |
1383 次 |
最近记录: |