求助:修改XSLT后基于HTML预览Apache FOP的XML转PDF效果
Hey there! Let's figure out how to get that PDF-style preview working in your HTML page. The core issue here is that browsers don't natively understand XSL-FO (the format your current XSLT generates for Apache FOP). We've got two solid approaches to solve this—either adjust your XSLT to output HTML for preview (while keeping the PDF generation intact) or embed the generated PDF directly in a web page. Let's dive into both, starting with the XSLT modification you asked for.
Option 1: Modify XSLT to Support Dual Output (HTML Preview + FO for PDF)
We can update your existing XSLT to conditionally generate either HTML (for browser preview) or XSL-FO (for PDF) using a parameter. This way, you use the same stylesheet for both workflows, keeping formatting consistent.
Here's the adjusted XSLT code tailored to your APJ Abdul Kalam example:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format"> <!-- Parameter to switch output type: 'html' for preview, 'fo' for PDF --> <xsl:param name="output-type" select="'fo'"/> <xsl:template match="/"> <xsl:choose> <!-- Generate HTML preview --> <xsl:when test="$output-type = 'html'"> <html> <head> <title><xsl:value-of select="data/title"/></title> <style> body { font-family: Helvetica; margin: 2cm; font-size: 13pt; } .page-header { color: green; font-size: 16pt; font-weight: bold; margin-bottom: 1cm; } .page-footer { font-size: 11pt; text-align: right; margin-top: 2cm; } .copyright { font-size: 8pt; text-align: center; margin-top: 0.5cm; } p { text-align: justify; margin-bottom: 3mm; } .external-link { color: red; font-size: 11pt; font-weight: bold; } </style> </head> <body> <div class="page-header"><xsl:value-of select="data/title"/></div> <p><xsl:value-of select="data/Para"/></p> <p><xsl:value-of select="data/Para[2]"/></p> <p><xsl:value-of select="data/Para[3]"/></p> <p>The details have been fetched from <a href="{data/url}" class="external-link"><xsl:value-of select="data/url"/></a></p> <div class="page-footer">Page 1 of 1</div> <div class="copyright">Copyright© 2022 Creation, All rights Reserved</div> </body> </html> </xsl:when> <!-- Original FO generation for PDF --> <xsl:otherwise> <fo:root> <fo:layout-master-set> <fo:simple-page-master master-name="simpleA4" page-height="29.7cm" page-width="21.0cm" margin="1cm"> <fo:region-body region-name="xsl-region-body" margin-top="1cm" margin-bottom="1cm"/> <fo:region-before region-name="xsl-region-before" extent="1cm"/> <fo:region-after region-name="xsl-region-after" extent="1cm"/> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-reference="simpleA4"> <fo:static-content flow-name="xsl-region-before"> <fo:block text-align="left" font-family="Helvetica" color="green" font-size="16pt" font-weight="bold"><xsl:value-of select="data/title"/></fo:block> </fo:static-content> <fo:static-content flow-name="xsl-region-after"> <fo:block text-align="right" font-size="11pt">Page <fo:page-number/> of <fo:page-number-citation ref-id="last-page"/></fo:block> <fo:block text-align="center" font-size="8pt">Copyright© 2022 Creation, All rights Reserved</fo:block> </fo:static-content> <fo:flow flow-name="xsl-region-body"> <fo:block text-align="justify" font-family="Helvetica" color="black" font-size="13pt" space-after="3mm"> <xsl:value-of select="data/Para"/> </fo:block> <fo:block text-align="justify" font-family="Helvetica" color="black" font-size="13pt" space-after="3mm"> <xsl:value-of select="data/Para[2]"/> </fo:block> <fo:block text-align="justify" font-family="Helvetica" color="black" font-size="13pt" space-after="3mm"> <xsl:value-of select="data/Para[3]"/> </fo:block> <fo:block text-align="justify" font-family="Helvetica" color="black" font-size="13pt" space-after="3mm">The details have been fetched from <fo:basic-link font-family="Helvetica" color="red" font-size="11pt" font-weight="bold" external-destination="url({data/url})"> <xsl:value-of select="data/url"/></fo:basic-link></fo:block> <fo:block id="last-page"/> </fo:flow> </fo:page-sequence> </fo:root> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>
How to use this:
Generate HTML preview: Pass the
output-type='html'parameter to your XSLT processor. For example, with Saxon:java -jar saxon-he-12.4.jar -s:your-data.xml -xsl:your-stylesheet.xsl -o:preview.html output-type=htmlOpen
preview.htmlin any browser to see a preview that matches your PDF's styling.Generate PDF as before: Use Apache FOP without the parameter (or with
output-type='fo') to get your original PDF output.
Option 2: Embed the Generated PDF in HTML
If you want to keep your original XSLT untouched, generate the PDF with Apache FOP first, then embed it in an HTML page using one of these tags:
<!DOCTYPE html> <html> <head> <title>APJ Abdul Kalam PDF Preview</title> </head> <body> <h1>Preview: A P J Abdul Kalam</h1> <!-- Option 1: Embed tag --> <embed src="your-generated.pdf" type="application/pdf" width="100%" height="800px"> <!-- Option 2: Iframe tag --> <!-- <iframe src="your-generated.pdf" width="100%" height="800px"></iframe> --> </body> </html>
This works in most modern browsers, though note some may require a PDF plugin or will prompt to download the file instead of displaying it.
Key Tips:
- The CSS in the HTML preview replicates your XSL-FO styling (font sizes, colors, margins) to ensure consistency. Tweak the CSS as needed to match your PDF exactly.
- The parameterized XSLT approach keeps a single source of truth for formatting, so you won't have to update styles in two places.
- For automated previews (e.g., when XML changes), you can use client-side JavaScript's
XSLTProcessorAPI to transform the XML to HTML directly in the browser.
内容的提问来源于stack exchange,提问作者AJAY S R

