Вы правы в своих исследованиях.
Ну, в основном, потому что важно различать метаданные, принадлежащие pdf-документу в целом, и метаданные, принадлежащие TIFF-изображению. Первый действительно ограничен одним экземпляром для pdf. Второе является независимым от метаданных pdf, но может быть добавлено как файл-вложение, что разрешено стандартом PDF/A-3. Оба типа не зависят от какой-либо страницы, поэтому в этом смысле ваш запрос Boss показывает отсутствие знаний о формате pdf как формате.
Однако вы можете разместить аннотацию ссылки на каждом Tiff, которая указывает на ее метада, которая может быть сохранена во втором файле pdf, что создает иллюзию того, что данные каким-то образом присутствуют на странице.
Теперь я должен с уважением не соглашаться с вашим заявлением о том, что iText не предоставляет вам инструменты для решения этой проблемы. Chapter 7 of the iText7 Jumpstart tutoria Я занимаюсь созданием PDF/A-X, включая встраивание файлов. PDF/A-3 - третий пример.
Что касается аннотаций ссылок, то они возможны с некоторыми знаниями о Pdf-spec (Embedded Go-To Actions) и низкоуровневых методах манипуляции iText. Сейчас у меня нет готового примера, но я посмотрю, смогу ли я что-нибудь придумать и добавить его к этому вопросу позже.
EDIT: Ну, это неутешительно, ни Foxit, ни читатели Adobe не поддерживают встроенные действия. Тем не менее, если вам интересно, ниже приведен код, который я использовал для создания документа, совместимого с PDF/A-3, с помощью iText7, добавляя метаданные в виде отдельного Pdf.
public static String INTENT = "src/test/resources/StackOverflow/EmbeddedLinking/sRGB_CS_profile.icm";
public static String IMG = "src/test/resources/StackOverflow/EmbeddedLinking/itis.jpg";
public static String META = "target/output/StackOverflow/EmbeddedLinking/metadata.pdf";
public static String DEST = "target/output/StackOverFlow/EmbeddedLinking/embeddedMetaData.pdf";
public static void main(String[] args) throws IOException, java.io.IOException {
File file = new File(DEST);
file.getParentFile().mkdirs();
new EmbeddedLinking().createPdf(META);
new EmbeddedLinking().createPdfWithEmbeddedFile(DEST,META,IMG,INTENT);
}
public void createPdf(String dest) throws IOException, FileNotFoundException{
PdfWriter writer = new PdfWriter(dest);
PdfDocument pdfDoc = new PdfDocument(writer);
Document doc = new Document(pdfDoc);
//Put some data here
doc.add(new Paragraph("This is the metadata"));
doc.add(new Paragraph("The Cake is Lie"));
doc.add(new Paragraph("42"));
doc.add(new Paragraph("The Spice must flow"));
doc.close();
}
public void createPdfWithEmbeddedFile(String dest, String embeddedPath, String imgPath, String intent) throws java.io.IOException {
PdfWriter writer = new PdfWriter(dest);
PdfOutputIntent outputIntent = new PdfOutputIntent("Custom", "","http://www.color.org", "sRGB IEC61966-2.1", new FileInputStream(intent));
PdfADocument pdfADoc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_3A,outputIntent);
//Setting some required parameters
pdfADoc.setTagged();
pdfADoc.getCatalog().setLang(new PdfString("en-US"));
pdfADoc.getCatalog().setViewerPreferences(
new PdfViewerPreferences().setDisplayDocTitle(true));
PdfDocumentInfo info = pdfADoc.getDocumentInfo();
info.setTitle("iText7 PDF/A-3 Embedded Go-To example");
//Add attachment
PdfDictionary parameters = new PdfDictionary();
parameters.put(PdfName.ModDate, new PdfDate().getPdfObject());
PdfFileSpec fileSpec = PdfFileSpec.createEmbeddedFileSpec(
pdfADoc, Files.readAllBytes(Paths.get(embeddedPath)), "metadata.pdf",
"metadata.pdf", new PdfName("application/pdf"), parameters,
PdfName.Data, false);
fileSpec.put(new PdfName("AFRelationship"), new PdfName("Data"));
pdfADoc.addFileAttachment("metadata.pdf", fileSpec);
PdfArray array = new PdfArray();
array.add(fileSpec.getPdfObject().getIndirectReference());
pdfADoc.getCatalog().put(new PdfName("AF"), array);
//Add Image
int imagePage = 1; //We know the image will end up on the first page since it's the only thing we add to the document
Document doc = new Document(pdfADoc, PageSize.A4);
Image img = new Image(ImageDataFactory.create(imgPath));
doc.add(img);
//Add link annotation to embedded file
float pageHeight = PageSize.A4.getHeight();
float imageWidth = img.getImageWidth();
float imageHeight = img.getImageHeight();
float x = doc.getLeftMargin();
float y = pageHeight - doc.getTopMargin() - imageHeight;
Rectangle linkAnnotationPosition = new Rectangle(x,y,imageWidth,imageHeight);
PdfLinkAnnotation linkAnnotation = new PdfLinkAnnotation(linkAnnotationPosition);
//Setup the Embedded GoTO action
PdfExplicitDestination explicitDestination = PdfExplicitDestination.createFit(imagePage);//Destination in the target file
PdfTargetDictionary targetDictionary = PdfTargetDictionary.createChildTarget("metadata.pdf"); //Target embedded file
PdfAction action = PdfAction.createGoToE(fileSpec,explicitDestination,true,targetDictionary);
linkAnnotation.setAction(action);
//PDF/A requires the presence of the F -bit flag array in every dictionary. The print flag needs to be 1, and some other flags 0.
//See the spec for details and options, but the bit pattern represented by the integer 4 suffices for conformance to PDF/A-3
int fBitArray = 4;
linkAnnotation.put(PdfName.F,new PdfNumber(fBitArray));
//Add annotation to page
pdfADoc.getPage(imagePage).addAnnotation(linkAnnotation);
//Close document
doc.close();
}
* «Согласно моим исследованиям в PDF Структуру/метаданных, похоже, должен быть только один XMP файл в формате PDF» * - там часто только один поток метаданных, который является один связан с документом в качестве целое. Тем не менее, может быть больше, см. Мой комментарий к ответу Самуила. – mkl