'Merging 2 PDF forms via layering
I have 2 acro-forms I'd like to merge.
One contains only text fields, the other contains an image field with hyperlink (QR code). Both are dynamically populated.
I'd like to merge the second one onto the first one (like an overlay, but not really).
Second form (first one is proprietary - so can't post it):
Here's what I've tried:
private fun prepareQrForm(qrTemplate: PDDocument, url: String): PDDocument {
val qrCode = encodeQr(url)
val acroForm = qrTemplate.documentCatalog.acroForm
val pdPushButton = acroForm.getField("qr")
val widget = pdPushButton.widgets.first()
val qrPdImageXObject = PDImageXObject.createFromByteArray(qrTemplate, qrCode, "qr")
val scaleRatio = qrPdImageXObject.height.toFloat() / qrPdImageXObject.width
val imageBoundingBox = widget.rectangle
val height = imageBoundingBox.height
val width = height / scaleRatio
val x = imageBoundingBox.lowerLeftX
val y = imageBoundingBox.lowerLeftY
val pdAppearanceStream = PDAppearanceStream(qrTemplate).apply {
resources = PDResources()
}
PDAppearanceContentStream(pdAppearanceStream).use {
it.drawImage(qrPdImageXObject, x, y, width, height)
}
if(widget.appearance == null) {
widget.appearance = PDAppearanceDictionary()
}
widget.appearance.setNormalAppearance(pdAppearanceStream)
// PDPageContentStream(qrTemplate, pdAppearanceStream).use {
// it.drawImage(qrPdImageXObject, x, y, width, height)
// }
pdAppearanceStream.bBox = PDRectangle(x, y, width, height)
val annotationLink = PDAnnotationLink().apply {
action = PDActionURI().apply {
uri = url
}
rectangle = imageBoundingBox
}
//the clickable area
qrTemplate.getPage(0).annotations.add(annotationLink)
return ByteArrayOutputStream().let { bos ->
qrTemplate.save(bos)
File("populated_qr_template.pdf").outputStream().use { it.write(bos.toByteArray()) }
PDDocument.load(bos.toByteArray())
}
}
The merger:
fun overlayPdf(
source: PDDocument,
sourcePage: PDPage = source.getPage(0),
target: PDDocument,
targetPage: PDPage
) {
val formObject = LayerUtility(target).importPageAsForm(source, sourcePage)
PDPageContentStream(target, targetPage, PDPageContentStream.AppendMode.APPEND, false, true).use {
it.drawForm(formObject)
}
}
The problem:
The resulting file does not contain the populated QR code, nor is clickable.
Expected:
The merged file should contain all content from both populated forms.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|

