danfickle/openhtmltopdf

Issue with embedded file attachments

osnard opened this issue · 0 comments

I have implemented a "custom resource access controller" as described on https://github.com/danfickle/openhtmltopdf/wiki/Embedding-downloadable-files#java

My HTML looks like this:

<a
    data-fs-embed-file="true"
    style="display:inline-block"
    href="attachments/Some_attachment.docx"
    class="internal media"
    title="Some attachment.docx"
    data-bs-title="Medium:Some attachment.docx"
    data-bs-filename="Some_attachment.docx"
    data-bs-filetimestamp="20240627142837"
    download="Some_attachment.docx"
    data-content-type="application/octet-stream"
    relationship="source">
Some attachment link
</a>

The resulting PDF contains

65 0 obj
<<
/Type /Filespec
/EF 109 0 R
/F (Some_attachment.docx)
/UF (Some_attachment.docx)
/AFRelationship /Source
/Desc (Some attachment.docx)
>>
endobj

The attachment link in the document works, but my PDF viewer (Xreader 3.6.6) does not show the proper filename in the "annotations" panel. It only shows "(null)". The "attachments" panel is empty.

image

I have tried different values for the download, data-content-type and relationship, but did not succeed.

I have read through the code at

private AnnotationContainer createFileEmbedLinkAnnotation(
Element elem, String uri) {
PDComplexFileSpecification fs = _embeddedFiles.get(uri);
if (fs != null) {
PDAnnotationFileAttachment annotationFileAttachment = new PDAnnotationFileAttachment();
annotationFileAttachment.setFile(fs);
annotationFileAttachment.setAppearance(this._embeddedFileAppearance);
return new AnnotationContainer.PDAnnotationFileAttachmentContainer(annotationFileAttachment);
}
byte[] file = _sharedContext.getUserAgentCallback().getBinaryResource(uri, ExternalResourceType.FILE_EMBED);
if (file != null) {
try {
String contentType = elem.getAttribute("data-content-type").isEmpty() ?
"application/octet-stream" :
elem.getAttribute("data-content-type");
PDEmbeddedFile embeddedFile = new PDEmbeddedFile(_od.getWriter(), new ByteArrayInputStream(file));
embeddedFile.setSubtype(contentType);
embeddedFile.setSize(file.length);
// PDF/A3 requires a mod date for the file.
if (elem.hasAttribute("relationship")) {
// FIXME: Should we make this specifiable.
embeddedFile.setModDate(Calendar.getInstance());
}
String fileName = elem.getAttribute("download");
fs = new PDComplexFileSpecification();
fs.setEmbeddedFile(embeddedFile);
fs.setFile(fileName);
fs.setFileUnicode(fileName);
// The PDF/A3 standard requires one to specify the relationship
// this embedded file has to the link annotation.
if (elem.hasAttribute("relationship") &&
Arrays.asList("Source", "Supplement", "Data", "Alternative", "Unspecified")
.contains(elem.getAttribute("relationship"))) {
fs.getCOSObject().setItem(
COSName.getPDFName("AFRelationship"),
COSName.getPDFName(elem.getAttribute("relationship")));
}
if (elem.hasAttribute("title")) {
fs.setFileDescription(elem.getAttribute("title"));
}
this._embeddedFiles.put(uri, fs);
if (this._embeddedFileAppearance == null) {
this._embeddedFileAppearance = createFileEmbedLinkAppearance();
}
PDAnnotationFileAttachment annotationFileAttachment = new PDAnnotationFileAttachment();
annotationFileAttachment.setFile(fs);
annotationFileAttachment.setAppearance(this._embeddedFileAppearance);
// PDF/A3 requires we explicitly list this link as associated with file.
if (elem.hasAttribute("relationship")) {
COSArray fileRefArray = new COSArray();
fileRefArray.add(fs);
annotationFileAttachment.getCOSObject().setItem(COSName.getPDFName("AF"), fileRefArray);
}
return new AnnotationContainer.PDAnnotationFileAttachmentContainer(annotationFileAttachment);
} catch (IOException e) {
XRLog.log(Level.WARNING, LogMessageId.LogMessageId1Param.EXCEPTION_COULD_NOT_LOAD_EMBEDDED_FILE, uri, e);
}
} else {
XRLog.log(Level.WARNING, LogMessageId.LogMessageId1Param.LOAD_COULD_NOT_LOAD_EMBEDDED_FILE, uri);
}
return null;
}
but didn't find anything.

Any ideas about what I am doing wrong?