### fop.xconf Configuration Example Source: https://context7.com/apache/xmlgraphics-fop/llms.txt An XML configuration file for FopFactory, controlling base URL, resolutions, default page settings, renderer options, and custom font embedding. ```xml /srv/app/resources 96 300 flate true true ``` -------------------------------- ### FOP Output Format Selection with MimeConstants Source: https://context7.com/apache/xmlgraphics-fop/llms.txt Demonstrates selecting FOP output renderers using MIME type strings. The correct MIME type is crucial for instantiating the appropriate renderer. ```java import org.apache.fop.apps.MimeConstants; import org.apache.fop.apps.FopFactory; import java.io.*; FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); // PDF Fop pdfFop = fopFactory.newFop(MimeConstants.MIME_PDF, fopFactory.newFOUserAgent(), new FileOutputStream("out.pdf")); // PostScript Fop psFop = fopFactory.newFop("application/postscript", fopFactory.newFOUserAgent(), new FileOutputStream("out.ps")); // RTF (no layout engine; page-breaking is done by the viewer) Fop rtfFop = fopFactory.newFop(MimeConstants.MIME_RTF, fopFactory.newFOUserAgent(), new FileOutputStream("out.rtf")); // PNG image (one image per page) Fop pngFop = fopFactory.newFop("image/png", fopFactory.newFOUserAgent(), new FileOutputStream("out.png")); // TIFF image Fop tiffFop = fopFactory.newFop("image/tiff", fopFactory.newFOUserAgent(), new FileOutputStream("out.tiff")); // PCL (Printer Command Language) Fop pclFop = fopFactory.newFop("application/vnd.hp-PCL", fopFactory.newFOUserAgent(), new FileOutputStream("out.pcl")); // AFP (IBM Advanced Function Presentation) Fop afpFop = fopFactory.newFop("application/x-afp", fopFactory.newFOUserAgent(), new FileOutputStream("out.afp")); // AWT on-screen preview (no output stream required) Fop awtFop = fopFactory.newFop(MimeConstants.MIME_FOP_AWT_PREVIEW, fopFactory.newFOUserAgent()); // FOP Intermediate Format XML (for deferred rendering / concatenation) Fop ifFop = fopFactory.newFop(MimeConstants.MIME_FOP_IF, fopFactory.newFOUserAgent(), new FileOutputStream("out.if.xml")); // FOP Area Tree XML (for deferred rendering / watermarking) Fop atFop = fopFactory.newFop(MimeConstants.MIME_FOP_AREA_TREE, fopFactory.newFOUserAgent(), new FileOutputStream("out.at.xml")); ``` -------------------------------- ### Create FopFactory Instance Source: https://context7.com/apache/xmlgraphics-fop/llms.txt Instantiate FopFactory using default configuration, an fop.xconf file, or a programmatic builder with custom settings. The factory is thread-safe and should be reused. ```java import org.apache.fop.apps.FopFactory; import org.apache.fop.apps.FopFactoryBuilder; import java.io.File; import java.net.URI; // 1. Minimal: default configuration, base URI = current directory FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); // 2. From an fop.xconf configuration file FopFactory fopFactoryFromConf = FopFactory.newInstance(new File("conf/fop.xconf")); // 3. Programmatic builder with custom settings URI baseURI = new File("/srv/app").toURI(); FopFactory fopFactoryCustom = new FopFactoryBuilder(baseURI) .setStrictUserConfigValidation(false) .setPageWidth("8.5in") .setPageHeight("11in") .build(); ``` -------------------------------- ### On-Screen Preview with AWT Source: https://context7.com/apache/xmlgraphics-fop/llms.txt Renders an XSL-FO document to an interactive AWT window for on-screen previewing. Output format is set to MIME_FOP_AWT_PREVIEW and no output stream is provided. ```java import org.apache.fop.apps.*; import javax.xml.transform.*; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.stream.StreamSource; import java.io.File; FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); public void previewFO(File foFile) throws Exception { // No output stream — AWT viewer handles display Fop fop = fopFactory.newFop(MimeConstants.MIME_FOP_AWT_PREVIEW); TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(); Source src = new StreamSource(foFile); Result res = new SAXResult(fop.getDefaultHandler()); transformer.transform(src, res); // An AWT window opens and displays the rendered document interactively } // Usage previewFO(new File("report.fo")); ``` -------------------------------- ### Convert XSL-FO to PDF using FopFactory Source: https://context7.com/apache/xmlgraphics-fop/llms.txt Construct a Fop instance using fopFactory.newFop() to render an XSL-FO document to a specified output format (e.g., PDF). Rendering is triggered via a JAXP Transformer output piped to fop.getDefaultHandler(). ```java import org.apache.fop.apps.*; import javax.xml.transform.*; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.stream.StreamSource; import java.io.*; public void convertFO2PDF(File foFile, File pdfFile) throws IOException, FOPException { FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); foUserAgent.setTitle("Hello World Document"); OutputStream out = new BufferedOutputStream(new FileOutputStream(pdfFile)); try { // Create FOP instance for PDF output Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out); // Identity transformer passes the FO file directly to FOP TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(); Source src = new StreamSource(foFile); Result res = new SAXResult(fop.getDefaultHandler()); transformer.transform(src, res); // Inspect results FormattingResults results = fop.getResults(); System.out.println("Total pages: " + results.getPageCount()); for (Object seq : results.getPageSequences()) { PageSequenceResults psr = (PageSequenceResults) seq; System.out.println(" Sequence '" + psr.getID() + "': " + psr.getPageCount() + " pages"); } } finally { out.close(); } } // Usage convertFO2PDF(new File("document.fo"), new File("output/document.pdf")); // Output: // Total pages: 3 // Sequence 'main': 3 pages ``` -------------------------------- ### Render FO to Intermediate Format (IF) XML Source: https://context7.com/apache/xmlgraphics-fop/llms.txt Renders a "from-fo" document into an Intermediate Format (IF) XML file. This is the first step in concatenating multiple documents. Requires FOP library and a valid FO source. ```java import org.apache.fop.apps.*; import org.apache.fop.render.intermediate.*; import org.apache.fop.render.intermediate.util.IFConcatenator; import javax.xml.transform.*; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.stream.*; import java.io.*; FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); // --- Step 1: Render two FO documents to Intermediate Format XML files --- public void renderToIF(Source foSource, Source xsltSource, File ifOutput) throws Exception { FOUserAgent userAgent = fopFactory.newFOUserAgent(); // Create the target PDF handler (needed for correct font setup in the IF) IFDocumentHandler targetHandler = userAgent.getRendererFactory() .createDocumentHandler(userAgent, MimeConstants.MIME_PDF); // Create the IFSerializer that mimics the target format IFSerializer ifSerializer = new IFSerializer(new IFContext(userAgent)); ifSerializer.mimicDocumentHandler(targetHandler); userAgent.setDocumentHandlerOverride(ifSerializer); OutputStream out = new BufferedOutputStream(new FileOutputStream(ifOutput)); try { Fop fop = fopFactory.newFop(null, userAgent, out); Transformer transformer = (xsltSource != null) ? TransformerFactory.newInstance().newTransformer(xsltSource) : TransformerFactory.newInstance().newTransformer(); transformer.transform(foSource, new SAXResult(fop.getDefaultHandler())); } finally { out.close(); } } // --- Step 2: Concatenate IF files into a single PDF --- public void concatIF2PDF(File[] ifFiles, File pdfOutput) throws Exception { FOUserAgent userAgent = fopFactory.newFOUserAgent(); IFDocumentHandler targetHandler = fopFactory.getRendererFactory() .createDocumentHandler(userAgent, MimeConstants.MIME_PDF); IFUtil.setupFonts(targetHandler); targetHandler.setResult(new StreamResult(pdfOutput)); IFConcatenator concatenator = new IFConcatenator(targetHandler, null); for (File f : ifFiles) { concatenator.appendDocument(new StreamSource(f)); } concatenator.finish(); // Finalizes and flushes the output PDF } // Usage File if1 = new File("out/chapter1.if.xml"); File if2 = new File("out/chapter2.if.xml"); renderToIF(new StreamSource(new File("chapter1.fo")), null, if1); renderToIF(new StreamSource(new File("chapter2.fo")), null, if2); concatIF2PDF(new File[]{if1, if2}, new File("out/full-book.pdf")); ``` -------------------------------- ### Batch Processing with FopFactory Reuse Source: https://context7.com/apache/xmlgraphics-fop/llms.txt Demonstrates efficient batch processing of multiple XSL-FO files by reusing FopFactory and TransformerFactory instances. FormattingResults are returned per rendering run for inspection. ```java import org.apache.fop.apps.*; import javax.xml.transform.*; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.stream.StreamSource; import java.io.*; // Both FopFactory and TransformerFactory are thread-safe and should be shared FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); TransformerFactory transformerFactory = TransformerFactory.newInstance(); public FormattingResults renderToPDF(File foFile, File pdfFile) throws Exception { FOUserAgent userAgent = fopFactory.newFOUserAgent(); OutputStream out = new BufferedOutputStream(new FileOutputStream(pdfFile)); Fop fop; try { fop = fopFactory.newFop(MimeConstants.MIME_PDF, userAgent, out); Transformer transformer = transformerFactory.newTransformer(); transformer.transform( new StreamSource(foFile), new SAXResult(fop.getDefaultHandler())); } finally { out.close(); } return fop.getResults(); } // Batch process an array of FO files File[] foFiles = { new File("page1.fo"), new File("page2.fo"), new File("page3.fo") }; for (File fo : foFiles) { File pdf = new File("out/" + fo.getName().replace(".fo", ".pdf")); FormattingResults results = renderToPDF(fo, pdf); System.out.printf("Rendered %s → %s (%d pages)%n", fo.getName(), pdf.getName(), results.getPageCount()); } // Output: // Rendered page1.fo → page1.pdf (2 pages) // Rendered page2.fo → page2.pdf (5 pages) // Rendered page3.fo → page3.pdf (1 pages) ``` -------------------------------- ### FopFactory.newFOUserAgent() Source: https://context7.com/apache/xmlgraphics-fop/llms.txt Creates a new FOUserAgent for each document rendering run. This object holds per-rendering-run metadata and options. ```APIDOC ## FopFactory.newFOUserAgent() ### Description Creates a new `FOUserAgent` instance for a single document rendering run. This object is essential for managing per-rendering-run metadata and options such as document title, author, target resolution, and custom renderer overrides. ### Method Signature ```java FOUserAgent newFOUserAgent() ``` ### Usage ```java import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.FopFactory; import java.io.File; import java.util.Date; FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); FOUserAgent userAgent = fopFactory.newFOUserAgent(); // Embed document metadata (stored in PDF Info dictionary) userAgent.setTitle("Annual Report 2024"); userAgent.setAuthor("Finance Department"); userAgent.setCreator("MyReportingApp 3.0"); userAgent.setKeywords("annual, report, 2024, finance"); userAgent.setCreationDate(new Date()); // Override output resolution for high-DPI bitmap rendering userAgent.setTargetResolution(300.0f); ``` ``` -------------------------------- ### FopFactory.newFop() Source: https://context7.com/apache/xmlgraphics-fop/llms.txt Constructs a Fop instance for rendering a single XSL-FO document to a specified output format. ```APIDOC ## FopFactory.newFop() ### Description Constructs a `Fop` instance that renders a single XSL-FO document to the chosen output format (e.g., PDF). Rendering is typically triggered by piping a JAXP `Transformer` output to `fop.getDefaultHandler()` via a `SAXResult`. After transformation, `fop.getResults()` can provide page-count statistics. ### Method Signature ```java Fop newFop(String mimeType, FOUserAgent userAgent, OutputStream outputStream) throws FOPException ``` ### Parameters * `mimeType` (String) - The MIME type of the desired output format (e.g., `MimeConstants.MIME_PDF`). * `userAgent` (FOUserAgent) - The user agent instance configured for this rendering run. * `outputStream` (OutputStream) - The output stream to write the rendered document to. ### Usage Example (XSL-FO to PDF) ```java import org.apache.fop.apps.*; import javax.xml.transform.*; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.stream.StreamSource; import java.io.*; public void convertFO2PDF(File foFile, File pdfFile) throws IOException, FOPException { FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); foUserAgent.setTitle("Hello World Document"); OutputStream out = new BufferedOutputStream(new FileOutputStream(pdfFile)); try { // Create FOP instance for PDF output Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out); // Identity transformer passes the FO file directly to FOP TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(); Source src = new StreamSource(foFile); Result res = new SAXResult(fop.getDefaultHandler()); transformer.transform(src, res); // Inspect results FormattingResults results = fop.getResults(); System.out.println("Total pages: " + results.getPageCount()); for (Object seq : results.getPageSequences()) { PageSequenceResults psr = (PageSequenceResults) seq; System.out.println(" Sequence '" + psr.getID() + "': " + psr.getPageCount() + " pages"); } } finally { out.close(); } } // Usage // convertFO2PDF(new File("document.fo"), new File("output/document.pdf")); ``` ``` -------------------------------- ### Convert XSL-FO to RTF using FOP Source: https://context7.com/apache/xmlgraphics-fop/llms.txt Switching renderers requires changing the MIME type argument to newFop(). FormattingResults.getResults() is not available for flow-based formats like RTF. ```java import org.apache.fop.apps.*; import javax.xml.transform.*; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.stream.StreamSource; import java.io.*; public void convertFO2RTF(File foFile, File rtfFile) throws IOException, FOPException { FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); OutputStream out = new BufferedOutputStream(new FileOutputStream(rtfFile)); try { // Only the MIME type differs from the PDF example Fop fop = fopFactory.newFop(MimeConstants.MIME_RTF, foUserAgent, out); TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(); Source src = new StreamSource(foFile); Result res = new SAXResult(fop.getDefaultHandler()); transformer.transform(src, res); // Note: fop.getResults() is NOT available for RTF } finally { out.close(); } } // Usage convertFO2RTF(new File("document.fo"), new File("out/document.rtf")); ``` -------------------------------- ### Convert DOM Document to PDF using FOP Source: https://context7.com/apache/xmlgraphics-fop/llms.txt Renders an XSL-FO DOM Document to PDF. Requires FOP library and JAXP transformer. The DOM can be built programmatically. ```java import org.apache.fop.apps.*; import javax.xml.parsers.*; import javax.xml.transform.*; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.sax.SAXResult; import org.w3c.dom.*; import java.io.*; static final String FO_NS = "http://www.w3.org/1999/XSL/Format"; public void convertDOM2PDF(Document foDocument, File pdfFile) throws Exception { FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); OutputStream out = new BufferedOutputStream(new FileOutputStream(pdfFile)); try { Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out); TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(); // identity Source src = new DOMSource(foDocument); Result res = new SAXResult(fop.getDefaultHandler()); transformer.transform(src, res); } finally { out.close(); } } // Build an FO DOM document in memory public static Document buildFODocument() throws ParserConfigurationException { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); Document doc = dbf.newDocumentBuilder().newDocument(); Element root = doc.createElementNS(FO_NS, "fo:root"); doc.appendChild(root); Element layoutSet = doc.createElementNS(FO_NS, "fo:layout-master-set"); root.appendChild(layoutSet); Element pageMaster = doc.createElementNS(FO_NS, "fo:simple-page-master"); pageMaster.setAttribute("master-name", "A4"); pageMaster.setAttribute("page-height", "297mm"); pageMaster.setAttribute("page-width", "210mm"); pageMaster.setAttribute("margin", "20mm"); layoutSet.appendChild(pageMaster); Element regionBody = doc.createElementNS(FO_NS, "fo:region-body"); pageMaster.appendChild(regionBody); Element pageSeq = doc.createElementNS(FO_NS, "fo:page-sequence"); pageSeq.setAttribute("master-reference", "A4"); root.appendChild(pageSeq); Element flow = doc.createElementNS(FO_NS, "fo:flow"); flow.setAttribute("flow-name", "xsl-region-body"); pageSeq.appendChild(flow); Element block = doc.createElementNS(FO_NS, "fo:block"); block.setTextContent("Hello, Apache FOP!"); flow.appendChild(block); return doc; } // Usage Document foDoc = buildFODocument(); convertDOM2PDF(foDoc, new File("out/dom-output.pdf")); ``` -------------------------------- ### Direct Printing with JPS Source: https://context7.com/apache/xmlgraphics-fop/llms.txt Integrates FOP with the Java Printing System to send formatted documents directly to a printer. A print dialog is shown for user selection. Ensure the JPS API is available. ```java import org.apache.fop.apps.*; import org.apache.fop.render.print.PageableRenderer; import javax.print.*; import javax.print.attribute.*; import javax.xml.transform.*; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.stream.StreamSource; import java.io.File; FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); public void printFO(File foFile) throws Exception { // Discover available print services that accept a Pageable PrintService[] services = PrintServiceLookup.lookupPrintServices( DocFlavor.SERVICE_FORMATTED.PAGEABLE, null); PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet(); // Show native print dialog for printer/options selection PrintService chosen = ServiceUI.printDialog( null, 50, 50, services, services[0], null, attributes); if (chosen == null) return; // user cancelled DocPrintJob printJob = chosen.createPrintJob(); // Configure FOP with a PageableRenderer FOUserAgent userAgent = fopFactory.newFOUserAgent(); PageableRenderer renderer = new PageableRenderer(userAgent); userAgent.setRendererOverride(renderer); Fop fop = fopFactory.newFop(userAgent); // no output stream; renderer handles output Transformer transformer = TransformerFactory.newInstance().newTransformer(); transformer.transform( new StreamSource(foFile), new SAXResult(fop.getDefaultHandler())); // Submit the pageable document to the selected printer Doc doc = new SimpleDoc(renderer, DocFlavor.SERVICE_FORMATTED.PAGEABLE, null); printJob.print(doc, null); } // Usage printFO(new File("invoice.fo")); ``` -------------------------------- ### Create FOUserAgent for Per-Run Metadata Source: https://context7.com/apache/xmlgraphics-fop/llms.txt Obtain a new FOUserAgent from FopFactory for each document rendering run to manage metadata like title, author, creator, keywords, creation date, and target resolution. ```java import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.FopFactory; import java.io.File; import java.util.Date; FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); FOUserAgent userAgent = fopFactory.newFOUserAgent(); // Embed document metadata (stored in PDF Info dictionary) userAgent.setTitle("Annual Report 2024"); userAgent.setAuthor("Finance Department"); userAgent.setCreator("MyReportingApp 3.0"); userAgent.setKeywords("annual, report, 2024, finance"); userAgent.setCreationDate(new Date()); // Override output resolution for high-DPI bitmap rendering userAgent.setTargetResolution(300.0f); // Use the configured userAgent in FOP rendering (see newFop examples below) ``` -------------------------------- ### Convert XML + XSLT to PDF in One Pass Source: https://context7.com/apache/xmlgraphics-fop/llms.txt Transform source XML into XSL-FO using an XSLT stylesheet and pipe the resulting SAX events directly into FOP for PDF generation, avoiding intermediate FO files. XSLT parameters can be set using transformer.setParameter(). ```java import org.apache.fop.apps.*; import javax.xml.transform.*; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.stream.StreamSource; import java.io.*; public void convertXML2PDF(File xmlFile, File xsltFile, File pdfFile) throws Exception { FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); OutputStream out = new BufferedOutputStream(new FileOutputStream(pdfFile)); try { // FOP receives the XSL-FO produced by the XSLT transformation Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out); // Load the XSLT stylesheet TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(new StreamSource(xsltFile)); // Inject an XSLT parameter transformer.setParameter("versionParam", "2.0"); // XML source → XSLT transformation → FOP (PDF) Source src = new StreamSource(xmlFile); Result res = new SAXResult(fop.getDefaultHandler()); transformer.transform(src, res); System.out.println("PDF generated: " + pdfFile.getAbsolutePath()); } finally { out.close(); } } // Usage convertXML2PDF( new File("data/report.xml"), new File("xslt/report2fo.xsl"), new File("out/report.pdf") ); ``` -------------------------------- ### Convert SVG to PDF using PDFTranscoder (Batik) Source: https://context7.com/apache/xmlgraphics-fop/llms.txt FOP's PDFTranscoder, built on Apache Batik, converts SVG files directly to PDF, bypassing the XSL-FO pipeline. The Batik Transcoder API is used by wrapping input and output in TranscoderInput/TranscoderOutput and calling transcode(). ```java import org.apache.batik.transcoder.*; import org.apache.fop.svg.PDFTranscoder; import java.io.*; public void convertSVG2PDF(File svgFile, File pdfFile) throws IOException, TranscoderException { Transcoder transcoder = new PDFTranscoder(); // Optionally set transcoder hints, e.g.: // transcoder.addTranscodingHint(PDFTranscoder.KEY_WIDTH, 595f); InputStream in = new FileInputStream(svgFile); try { TranscoderInput input = new TranscoderInput(in); OutputStream out = new BufferedOutputStream(new FileOutputStream(pdfFile)); try { TranscoderOutput output = new TranscoderOutput(out); transcoder.transcode(input, output); System.out.println("SVG converted to PDF: " + pdfFile.getAbsolutePath()); } finally { out.close(); } } finally { in.close(); } } // Usage convertSVG2PDF(new File("diagram.svg"), new File("out/diagram.pdf")); ``` -------------------------------- ### Implement Custom Event Listeners in FOP Source: https://context7.com/apache/xmlgraphics-fop/llms.txt Register event listeners to intercept and handle FOP processing events. One listener logs events by severity, while another aborts processing on missing images. Ensure the necessary FOP libraries are included. ```java import org.apache.fop.apps.*; import org.apache.fop.events.*; import org.apache.fop.events.model.EventSeverity; import javax.xml.transform.*; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.stream.StreamSource; import java.io.*; import java.net.FileNotFoundException; FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); // Listener 1: log all events to stdout/stderr by severity foUserAgent.getEventBroadcaster().addEventListener(event -> { String msg = EventFormatter.format(event); EventSeverity sev = event.getSeverity(); if (sev == EventSeverity.INFO) System.out.println("[INFO ] " + msg); else if (sev == EventSeverity.WARN) System.out.println("[WARN ] " + msg); else if (sev == EventSeverity.ERROR) System.err.println("[ERROR] " + msg); else if (sev == EventSeverity.FATAL) System.err.println("[FATAL] " + msg); }); // Listener 2: abort processing when an image is missing foUserAgent.getEventBroadcaster().addEventListener(event -> { if ("org.apache.fop.ResourceEventProducer.imageNotFound" .equals(event.getEventID())) { FileNotFoundException fnfe = (FileNotFoundException) event.getParam("fnfe"); throw new RuntimeException( "Missing image: " + event.getParam("uri"), fnfe); } }); // Normal rendering pipeline OutputStream out = new BufferedOutputStream(new FileOutputStream("out.pdf")); try { Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out); Transformer transformer = TransformerFactory.newInstance().newTransformer(); transformer.transform( new StreamSource(new File("document-with-images.fo")), new SAXResult(fop.getDefaultHandler())); } finally { out.close(); } // If an image is missing, a RuntimeException is thrown from within transformer.transform(). ``` -------------------------------- ### XML + XSLT to PDF Conversion Source: https://context7.com/apache/xmlgraphics-fop/llms.txt Transforms source XML into XSL-FO using an XSLT stylesheet, then directly into PDF in a single pass. ```APIDOC ## XML + XSLT to PDF Conversion ### Description This process integrates FOP with JAXP's XSLT engine to transform source XML into XSL-FO, which is then directly rendered to PDF. This pipeline avoids creating an intermediate XSL-FO file. XSLT parameters can be injected into the transformation process. ### Method Signature ```java void convertXML2PDF(File xmlFile, File xsltFile, File pdfFile) throws Exception ``` ### Parameters * `xmlFile` (File) - The source XML file. * `xsltFile` (File) - The XSLT stylesheet to transform XML to XSL-FO. * `pdfFile` (File) - The output PDF file. ### Usage Example ```java import org.apache.fop.apps.*; import javax.xml.transform.*; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.stream.StreamSource; import java.io.*; public void convertXML2PDF(File xmlFile, File xsltFile, File pdfFile) throws Exception { FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); OutputStream out = new BufferedOutputStream(new FileOutputStream(pdfFile)); try { // FOP receives the XSL-FO produced by the XSLT transformation Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out); // Load the XSLT stylesheet TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(new StreamSource(xsltFile)); // Inject an XSLT parameter transformer.setParameter("versionParam", "2.0"); // XML source → XSLT transformation → FOP (PDF) Source src = new StreamSource(xmlFile); Result res = new SAXResult(fop.getDefaultHandler()); transformer.transform(src, res); System.out.println("PDF generated: " + pdfFile.getAbsolutePath()); } finally { out.close(); } } // Usage // convertXML2PDF( // new File("data/report.xml"), // new File("xslt/report2fo.xsl"), // new File("out/report.pdf") // ); ``` ``` -------------------------------- ### Stamp/Watermark PDF using Area Tree XML Source: https://context7.com/apache/xmlgraphics-fop/llms.txt Applies an XSLT stylesheet to an Area Tree XML file to stamp or watermark the document before rendering it to PDF. Requires FOP library, Area Tree XML, and an XSLT stylesheet. ```java import org.apache.fop.apps.*; import org.apache.fop.area.*; import org.apache.fop.fonts.FontInfo; import javax.xml.transform.*; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.stream.StreamSource; import java.io.*; FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); public void stampToPDF(File areaTreeFile, File stampXslt, File pdfOutput) throws Exception { OutputStream out = new BufferedOutputStream(new FileOutputStream(pdfOutput)); try { FontInfo fontInfo = new FontInfo(); FOUserAgent userAgent = fopFactory.newFOUserAgent(); // RenderPagesModel drives the final PDF renderer AreaTreeModel treeModel = new RenderPagesModel( userAgent, MimeConstants.MIME_PDF, fontInfo, out); // Apply the stamp XSLT to the area tree XML and feed into AreaTreeParser AreaTreeParser parser = new AreaTreeParser(); Transformer transformer = TransformerFactory.newInstance() .newTransformer(new StreamSource(stampXslt)); SAXResult res = new SAXResult( parser.getContentHandler(treeModel, userAgent)); transformer.transform(new StreamSource(areaTreeFile), res); // Finalize the PDF output treeModel.endDocument(); } finally { out.close(); } } // Usage: stamp.xsl injects a "CONFIDENTIAL" watermark block into the area tree stampToPDF( new File("out/document.at.xml"), new File("xslt/watermark.xsl"), new File("out/document-stamped.pdf") ); ```