嗨,我正在使用fop从XML文件生成PDF
Java 11版本Spring引导启动程序2.5.2
组织。Apache。可扩展标记图形(fop)版本2.7
我收到此错误
org.apache.fop.fo.ValidationException:fo:region-body "xsl-region-body"的边框和填充应为"0"(请参见XSL 1.1中的6.4.14);如果启用了宽松验证,则允许使用非标准值。(没有可用的上下文信息)
请帮帮忙
'
Starter.java
package pack;
import java.io.File;import java.io.OutputStream;import java.net.URI;
import javax.xml.transform.Result;import javax.xml.transform.Source;import javax.xml.transform.Transformer;import javax.xml.transform.TransformerFactory;import javax.xml.transform.sax.SAXResult;import javax.xml.transform.stream.StreamSource;
import org.apache.avalon.framework.configuration.Configuration;import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;import org.apache.fop.apps.FOUserAgent;import org.apache.fop.apps.Fop;import org.apache.fop.apps.FopFactory;import org.apache.fop.apps.FopFactoryBuilder;import org.apache.fop.apps.MimeConstants;import org.apache.fop.events.Event;import org.apache.fop.events.EventListener;import org.apache.fop.events.model.EventSeverity;
public class Start {
public static void main(String[] args) throws Exception {
System.out.println("FOP ExampleXML2PDF");
// Setup input and output files
File xmlfile = new File("src/main/resources/article.xml");
File xsltfile = new File("src/main/resources/article2fo.xsl");
File pdffile = new File("article.pdf");
System.out.println("Input: XML (" + xmlfile + ")");
System.out.println("Stylesheet: " + xsltfile);
System.out.println("Output: PDF (" + pdffile + ")");
System.out.println("Transforming...");
// NOTE: reuse fopFactory
// FopFactory fopFactory = getFopFactoryConfiguredFromClasspath("fop.xconf.xml");// FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI());// FOUserAgent foUserAgent = fopFactory.newFOUserAgent();// FopFactory fopFactory = getFopFactoryConfiguredFromFileSystem("fop.xconf.xml");//test by uday startFopFactory fopFactory = getFopFactoryConfiguredFromClasspath("fop.xconf.xml");FOUserAgent userAgent = fopFactory.newFOUserAgent();userAgent.getEventBroadcaster().addEventListener(getInvalidPropertyEventListener());//test by uday end// with userAgent you can further configure some things:// https://xmlgraphics.apache.org/fop/2.2/embedding.html#user-agent//FOUserAgent foUserAgent = fopFactory.newFOUserAgent();// configure foUserAgent as desired
// Setup output
OutputStream out = new java.io.FileOutputStream(pdffile);
out = new java.io.BufferedOutputStream(out);
try {
// Construct fop with desired output format
// Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent,out);
// Setup XSLT
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(new StreamSource(xsltfile));
// Set the value of a <param> in the stylesheet
transformer.setParameter("versionParam", "2.0");
// Setup input for XSLT transformation
Source src = new StreamSource(xmlfile);
// Resulting SAX events (the generated FO) must be piped through to FOP
Result res = new SAXResult(fop.getDefaultHandler());
// Start XSLT transformation and FOP processing
transformer.transform(src, res);
} finally {
out.close();
}
System.out.println("Success!");
}
private static EventListener getInvalidPropertyEventListener() {
Start.InvalidPropertyEventListener lsn = new Start.InvalidPropertyEventListener();
return lsn;
}
private static class InvalidPropertyEventListener implements EventListener {
/**
* Continues processing even if an <code>invalidProperty</code> runtimeException was thrown
* during FO to PDF transformation.
* <p>
* Descends the event's severity level to WARN to avoid the exception throwing.
*
* @param event The event to be processed.
*/
@Override
public void processEvent(Event event) {
if ("org.apache.fop.fo.FOValidationEventProducer.invalidProperty".equals(event.getEventID())) {
event.setSeverity(EventSeverity.WARN);
}
}
}
/**
* The fop configuration and referenced resources (ttf font) are loaded
* from the file system
*
*/
private static FopFactory getFopFactoryConfiguredFromFileSystem(String configFileName) throws Exception {
FopFactory fopFactory = FopFactory.newInstance(new File("src/main/resources/" + configFileName));
return fopFactory;
}
/**
* The fop configuration and referenced resources (ttf font) are loaded
* from the classpath
*
*/
private static FopFactory getFopFactoryConfiguredFromClasspath(String configFileName) throws Exception {
URI baseUri = URI.create("base_uri_is_meaningless_in_this_case");
// System.out.println("uri: " + uri);
// create a builder with a ResourceResolver which reads from the classpath.
// The resourceResolver will be called for loading the resources referenced
// in the configuration (for example a ttf font)
FopFactoryBuilder builder = new FopFactoryBuilder(baseUri, new ClasspathResolverURIAdapter());
// create a configuration which is based on a file read from the classpath
DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder();
Configuration cfg = cfgBuilder.build(Start.class.getResourceAsStream("/" + configFileName));
// sets the configuration
builder.setConfiguration(cfg);
FopFactory fopFactory = builder.build();
return fopFactory;
}
}
ClasspathResolverURIAdapter.java
`package pack;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import org.apache.fop.apps.io.ResourceResolverFactory;
import org.apache.fop.events.Event;
import org.apache.fop.events.EventListener;
import org.apache.fop.events.model.EventSeverity;
import org.apache.xmlgraphics.io.Resource;
import org.apache.xmlgraphics.io.ResourceResolver;
/**
* ResourceResolver which loads resources with "classpath:" prefix from the
* classpath
*
* Based on this:
*
* https://stackoverflow.com/questions/41661997/set-fopfactorybuilder-baseuri-to-jar-classpath
*
*/
public class ClasspathResolverURIAdapter implements ResourceResolver {
private final ResourceResolver wrapped;
public ClasspathResolverURIAdapter() {
this.wrapped = ResourceResolverFactory.createDefaultResourceResolver();
}
@Override
public Resource getResource(URI uri) throws IOException {
System.out.println("getresource called, uri is: " + uri + ", path is: " + uri.getSchemeSpecificPart());
if (uri.getScheme().equals("classpath")) {
InputStream is = Start.class.getResourceAsStream(uri.getSchemeSpecificPart());
System.out.println("is: " + is);
return new Resource(is);
} else {
return wrapped.getResource(uri);
}
}
@Override
public OutputStream getOutputStream(URI uri) throws IOException {
if (uri.getScheme().equals("classpath")) {
throw new RuntimeException("This is a read only ResourceResolver. You can not use it's outputstream");
} else {
return wrapped.getOutputStream(uri);
}
}
}`
article2fo.xsl文件
`<?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"
xmlns:lgcy="urn:tarhely.gov.hu:1.0:legacy"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="header1">
<fo:block font-size="24pt">
<xsl:apply-templates select="node()"/>
</fo:block>
</xsl:template>
<xsl:template match="para">
<fo:block font-size="12pt">
<xsl:apply-templates select="node()"/>
</fo:block>
</xsl:template>
<xsl:template match="/">
<!--
<fo:root>
-->
<fo:root font-family="FreeSans">
<fo:layout-master-set>
<fo:simple-page-master master-name="A4-portrait"
page-height="29.7cm" page-width="21.0cm" margin="2cm">
<fo:region-body margin-bottom="0.5in" border="solid"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4-portrait">
<fo:flow flow-name="xsl-region-body">
<xsl:copy>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xsl:stylesheet>`
fop.xconf.xml
`<?xml version="1.0"?>
<!-- $Id: fop.xconf 1616312 2014-08-06 19:19:31Z gadams $ -->
<!--
This is a shortened example configuration file for FOP.
Based on the fop.xconf from the distribution zip.
-->
<!-- NOTE: This is the version of the configuration -->
<fop version="1.0">
<!-- Base URL for resolving relative URLs -->
<base>.</base>
<!-- Source resolution in dpi (dots/pixels per inch) for determining the size of pixels in SVG and bitmap images, default: 72dpi -->
<source-resolution>72</source-resolution>
<!-- Target resolution in dpi (dots/pixels per inch) for specifying the target resolution for generated bitmaps, default: 72dpi -->
<target-resolution>72</target-resolution>
<!-- Default page-height and page-width, in case value is specified as auto -->
<default-page-settings height="11.00in" width="8.50in"/>
<!-- Information for specific renderers -->
<!-- Uses renderer mime type for renderers -->
<renderers>
<renderer mime="application/pdf">
<filterList>
<!-- provides compression using zlib flate (default is on) -->
<value>flate</value>
<!-- encodes binary data into printable ascii characters (default off)
This provides about a 4:5 expansion of data size -->
<!-- <value>ascii-85</value> -->
<!-- encodes binary data with hex representation (default off)
This filter is not recommended as it doubles the data size -->
<!-- <value>ascii-hex</value> -->
</filterList>
<fonts>
<!-- embedded fonts -->
<!--
This information must exactly match the font specified
in the fo file. Otherwise it will use a default font.
For example,
<fo:inline font-family="Arial" font-weight="bold" font-style="normal">
Arial-normal-normal font
</fo:inline>
for the font triplet specified by:
<font-triplet name="Arial" style="normal" weight="bold"/>
If you do not want to embed the font in the pdf document
then do not include the "embed-url" attribute.
The font will be needed where the document is viewed
for it to be displayed properly.
possible styles: normal | italic | oblique | backslant
possible weights: normal | bold | 100 | 200 | 300 | 400
| 500 | 600 | 700 | 800 | 900
(normal = 400, bold = 700)
-->
<!--
FreeSans.ttf is from Xubuntu's /usr/share/fonts/truetype/freefont folder
-->
<!-- use this for classpath based configuration
<font kerning="yes" embed-url="classpath:/FreeSans.ttf">
-->
<!-- use this for file system based configuration
<font kerning="yes" embed-url="FreeSans.ttf">
-->
<font kerning="yes" embed-url="classpath:/FreeSans.ttf">
<font-triplet name="FreeSans" style="normal" weight="normal"/>
</font>
<!-- auto-detect fonts -->
<!--
<auto-detect/>
-->
</fonts>
<!-- This option lets you specify additional options on an XML handler -->
<!--xml-handler namespace="http://www.w3.org/2000/svg">
<stroke-text>false</stroke-text>
</xml-handler-->
</renderer>
</renderers>
</fop>`
1条答案
按热度按时间e4eetjau1#
您可以尝试将XSL-FO文档中的fo:region-body元素的值设置为零,也可以尝试在运行FOP之前通过将"fop.xsl.extensions.config" Java系统属性设置为"fop.extensions.xsl-fo-extensions.xml"来启用宽松验证。
复制代码
这将允许使用非标准值。请注意,启用宽松验证可能会导致其他错误,因此不建议在生产中使用。