Created
November 12, 2025 00:36
-
-
Save mgaffigan/c5bda641ba45c8189be877eb155d773e to your computer and use it in GitHub Desktop.
Stamp a PDF in Mirth
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var PDDocument = org.apache.pdfbox.pdmodel.PDDocument; | |
| var PDPage = org.apache.pdfbox.pdmodel.PDPage; | |
| var PDPageContentStream = org.apache.pdfbox.pdmodel.PDPageContentStream; | |
| var PDType1Font = org.apache.pdfbox.pdmodel.font.PDType1Font; | |
| var Standard14Fonts = org.apache.pdfbox.pdmodel.font.Standard14Fonts; | |
| var PDImageXObject = org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; | |
| var PDFTextStripper = org.apache.pdfbox.text.PDFTextStripper; | |
| var TextPosition = org.apache.pdfbox.text.TextPosition; | |
| var File = java.io.File; | |
| var HashMap = java.util.HashMap; | |
| var ArrayList = java.util.ArrayList; | |
| /** | |
| * BoundingPoint - represents a point in 2D space | |
| */ | |
| function BoundingPoint(x, y) { | |
| this.x = x; | |
| this.y = y; | |
| } | |
| /** | |
| * BoundingBox - represents a rectangular area with type information | |
| */ | |
| function BoundingBox(type, bottomLeft, topRight) { | |
| this.type = type; | |
| // Determine the actual bottom-left and top-right coordinates | |
| var actualBottomLeftX = Math.min(bottomLeft.x, topRight.x); | |
| var actualBottomLeftY = Math.min(bottomLeft.y, topRight.y); | |
| var actualTopRightX = Math.max(bottomLeft.x, topRight.x); | |
| var actualTopRightY = Math.max(bottomLeft.y, topRight.y); | |
| this.x = actualBottomLeftX; | |
| this.y = actualBottomLeftY; | |
| this.width = actualTopRightX - actualBottomLeftX; | |
| this.height = actualTopRightY - actualBottomLeftY; | |
| } | |
| /** | |
| * TextLocationStripper - extends PDFTextStripper to find markers in PDF text | |
| */ | |
| function TextLocationStripper() { | |
| var symbols = ["s<", "i<", ">s", ">i"]; | |
| var unmatchedPoints = new HashMap(); | |
| var boundingRects = []; | |
| return new JavaAdapter(PDFTextStripper, { | |
| boundingRects: boundingRects, | |
| writeString: function(string, textPositions) { | |
| string = String(string); | |
| if (string.length === 2 && symbols.indexOf(string) !== -1) { | |
| var marker = string.replace("<", "").replace(">", ""); | |
| var pos = textPositions.get(0); | |
| var newPoint = new BoundingPoint(pos.getX(), pos.getPageHeight() - pos.getY()); | |
| var unmatched = unmatchedPoints.remove(marker); | |
| if (unmatched == null) { | |
| unmatchedPoints.put(marker, newPoint); | |
| } else { | |
| this.boundingRects.push(new BoundingBox(marker, unmatched, newPoint)); | |
| } | |
| } | |
| } | |
| }); | |
| } | |
| /** | |
| * Find bounding boxes on a specific page | |
| */ | |
| function findBoundingBoxesOnPage(document, pageIndex) { | |
| var stripper = new TextLocationStripper(); | |
| stripper.setStartPage(pageIndex + 1); | |
| stripper.setEndPage(pageIndex + 1); | |
| var text = stripper.getText(document); | |
| return stripper.boundingRects; | |
| } | |
| /** | |
| * Main stamping function - equivalent to the Java stampPdf method | |
| * | |
| * @param {string} inputPdfPath - Path to input PDF file | |
| * @param {string} signatureImagePath - Path to signature image file | |
| * @param {string} metadataText - Metadata text to stamp (semicolon-separated) | |
| * @param {string} outputPdfPath - Path for output PDF file | |
| */ | |
| function stampPdf(inputPdfPath, signatureImagePath, metadataText, outputPdfPath) { | |
| var document = PDDocument.load(new File(inputPdfPath)); | |
| try { | |
| //logger.info("Loaded PDF with " + document.getNumberOfPages() + " pages"); | |
| var signatureImage = PDImageXObject.createFromFile(signatureImagePath, document); | |
| for (var pageIndex = 0; pageIndex < document.getNumberOfPages(); pageIndex++) { | |
| var page = document.getPage(pageIndex); | |
| var boxes = findBoundingBoxesOnPage(document, pageIndex); | |
| var contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true, true); | |
| try { | |
| for (var i = 0; i < boxes.length; i++) { | |
| var box = boxes[i]; | |
| if ("i" === box.type) { | |
| contentStream.beginText(); | |
| contentStream.setFont(PDType1Font.HELVETICA, 8.0); | |
| contentStream.newLineAtOffset(box.x, box.y); | |
| contentStream.showText('Hello World'); | |
| contentStream.endText(); | |
| } | |
| } | |
| } finally { | |
| contentStream.close(); | |
| } | |
| } | |
| document.save(outputPdfPath); | |
| } finally { | |
| document.close(); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment