OpenPDF的学习文档(第六章·PDF元数据和归档标准)
PDF元数据
- 所谓的元数据Metadata,就是PDF文档的属性信息,不是打印在PDF页面上的。
addAuthor(String author)添加作者,一般是创作人或组织。(张三,某某组织,某某办公室)addCreator(String creator)添加创建者,生成文档的上游系统或软件。(某某系统,Microsoft Word)addProducer()添加生产者,一般是底层渲染库。(OpenPDF, iText, PDF-XChange Editor)addCreationDate(PdfDate date)添加创建日期addModificationDate(PdfDate date)添加修改日期addKeywords(String keywords)添加关键字addSubject(String subject)添加主题addTitle(String title)添加标题![image]()
addHeader(String name, String content)添加自定义的PDF元信息。- 严重警告:在
document.open();之前使用。 -
PdfWriter writer = PdfWriter.getInstance(document, outputStream); document.addAuthor("作者"); document.addCreator("创建者"); document.addProducer(); // 添加生产者 document.addCreationDate(); // 创建日期 document.addModificationDate(); // 修改日期 document.addKeywords("关键字"); document.addSubject("PDF主题"); // PDF主题 document.addTitle("PDF标题"); // PDF标题 document.open(); document.add(new Paragraph("Hi")); document.close();
归档标准 PDF/A(Portable Document Format for Archival)
- PDF归档:目的是确保文档在未来几十年甚至几百年后打开时,其外观、结构和可读性与最初创建时完全一致
- ISO 标准组织(ISO 19005 系列) 主持创建标准。
- 迄今为止,ISO组织一共发布了4代PDF/A标准
-
PDF/A-1(ISO 19005-1:2005,基于 PDF 1.4)
-
PDF/A-2(ISO 19005-2:2011,基于 PDF 1.7)
-
PDF/A-3(ISO 19005-3:2012,基于 PDF 1.7)
-
PDF/A-4(ISO 19005-4:2020,基于 PDF 2.0)
-
PDF/A-1 到 PDF/A-3 中:有三个级别
- -b:基本级,只保证视觉呈现一致。
- -u:文本检索级,所有字符都有对应的 Unicode 映射,保证文本可以被正确复制和搜索。
- -a:无障碍/结构化级,标签化 PDF(Tagged PDF)、标注文章逻辑顺序(如标题、段落、表格结构)、方便盲人阅读器等无障碍设备读取。
-
PDF/A-4 废弃了上述三个级别
- PDF/A-4:基础模式
- PDF/A-4f:允许嵌入非 PDF/A 的任意格式附件
- PDF/A-4e:针对工程和 3D 图纸领域的归档
-
- 在OpenPDF的
PdfWriter类中,找到了一些关于PDF/A标准的常量。 -
/** * A PDF/X level. */ public static final int PDFXNONE = 0; /** * A PDF/X level. */ public static final int PDFX1A2001 = 1; // Open and Close methods + method that create the PDF /** * A PDF/X level. */ public static final int PDFX32002 = 2; /** * PDFA-1A level. */ public static final int PDFA1A = 3; /** * PDFA-1B level. */ public static final int PDFA1B = 4; /** * PDFA-2A level. */ public static final int PDFA2A = 5; /** * PDFA-2B level. */ public static final int PDFA2B = 6; /** * PDFA-2U level. */ public static final int PDFA2U = 7; /** * PDFA-3A level. */ public static final int PDFA3A = 8; /** * PDFA-3B level. */ public static final int PDFA3B = 9; /** * PDFA-3U level. */ public static final int PDFA3U = 10; - 找到了一份官网示例,创建符合PDF/A-1b的PDF
-
public class PdfA1B { /** * Creates a document validating PDF/A-1b conformance * * @param args no arguments needed here */ public static void main(String[] args) { System.out.println("PDF/A-1b"); // step 1: creation of a document-object Document document = new Document(); try { // step 2: create writer and set conformance PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("PdfA1b.pdf")); // 关键点:设置PDFA1B属性。 // 但是我没有搞明白PDF/A为什么要和PDF/X方法里校验 writer.setPDFXConformance(PDFA1B); // step 3: open the document document.open(); // create pdf dictionary with required entry PdfDictionary pdfDictionary = new PdfDictionary(); pdfDictionary.put(PdfName.CREATIONDATE, writer.getInfo().get(PdfName.CREATIONDATE)); pdfDictionary.put(PdfName.MODDATE, writer.getInfo().get(PdfName.MODDATE)); try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { // embed dictionary in XmpWriter XmpWriter xmpWriter = new XmpWriter(baos, pdfDictionary, PdfWriter.PDFA1B); xmpWriter.close(); byte[] xmpMetadata = baos.toByteArray(); // set xmp metadata and output intents writer.setXmpMetadata(xmpMetadata); writer.setOutputIntents("Custom", "", null, "sRGB IEC61966-2.1", ICC_Profile.getInstance(ColorSpace.CS_sRGB)); } // step 4: // we make some content String fontDir = "org/openpdf/examples/fonts/"; BaseFont notoBase = BaseFont.createFont( Objects.requireNonNull( PdfA1B.class.getClassLoader().getResource(fontDir + "noto/NotoSans-Regular.ttf")).getFile(), BaseFont.IDENTITY_H, BaseFont.EMBEDDED); Font noto = new Font(notoBase, 10, Font.NORMAL); // a paragraph Paragraph p1 = new Paragraph("This document is compliant with PDF-A/1b requirements", noto); // some paragraph Paragraph p2 = new Paragraph("blah, blah, blah", noto); // we add the content document.add(p1); document.add(p2); document.add(p2); document.add(p2); document.add(p2); document.add(p2); document.add(p2); document.add(p2); } catch (DocumentException | IOException de) { System.err.println(de.getMessage()); } // step 5: we close the document document.close(); } } - 这里的例子有很大的问题,OpenPDF根本没有校验PDFA1B的逻辑。
- 有兴趣的可以查看PdfXConformanceImp.checkPDFXConformance(PdfWriter writer, int key, Object obj1)和PdfXConformance.setPDFXConformance(int pdfxConformance)源码。
PDF/X 印刷保证。
- PDF/X-1a
- PDF/X-3
- PDF/X-4
- PDF/X-6
- OpenPDF只能保证PDF/X-1a:2001,还不一定全面。


浙公网安备 33010602011771号