Java 将 XML 文档渲染为 PDF
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14359810/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java Render XML Document as PDF
提问by Javaddict
I have an XML document currently stored as an in-memory string & want to render it as a PDF. In other words, the PDF content will be an XML document. The XML being rendered by the method is generic -- multiple types of XML documents might be sent in.
我有一个 XML 文档当前存储为内存中的字符串并希望将其呈现为 PDF。换句话说,PDF 内容将是一个 XML 文档。该方法呈现的 XML 是通用的——可能会发送多种类型的 XML 文档。
I'm having a bit difficulty figuring out how to accomplish using using various Java-based frameworks.
我很难弄清楚如何使用各种基于 Java 的框架来完成。
Apache FOP
阿帕奇FOP
It appears as if this framework require specific transformation for XML elements in the document to FOP entities. Since the method in questions must accept generic XML, I don't think this framework fits my requirement.
该框架似乎需要将文档中的 XML 元素特定转换为 FOP 实体。由于问题中的方法必须接受通用 XML,因此我认为此框架不符合我的要求。
iText
文本
I've tried rendering a document using a combination of iText/Flying Saucer (org.xhtmlrenderer) and while it does render a PDF, the content only contains space-separated data values and no xml elements or attributes. Using the code & test data below below:
我尝试使用 iText/Flying Saucer (org.xhtmlrenderer) 的组合来呈现文档,虽然它确实呈现了 PDF,但内容仅包含空格分隔的数据值,没有 xml 元素或属性。使用下面的代码和测试数据:
File
文件
<?xml version="1.0" encoding="UTF-8"?>
<root>
<elem1>value1</elem1>
<elem2>value2</elem2>
</root>
Code
代码
File inputFile = new File(PdfGenerator.class.getResource("test.xml").getFile());
OutputStream os = new FileOutputStream("c:\temp\Sample.pdf");
ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(inputFile);
renderer.layout();
renderer.createPDF(os);
os.close();
Results in a PDF that contains the content values value1 value2
, but no tags.
生成包含内容值value1 value2
但不包含标签的 PDF 。
My question iscan someone provide a code snippet for rending a PDF containing XML content using one of the frameworks above, or is there another framework better suited to my needs?
我的问题是有人可以提供一个代码片段来使用上述框架之一来呈现包含 XML 内容的 PDF,还是有另一个更适合我的需求的框架?
Edit:I realize the same question was asked here, but it seems the solution presented requires intimate knowledge of the structure of the incoming XML doc in the css file.
编辑:我意识到这里提出了同样的问题,但似乎提出的解决方案需要对 css 文件中传入的 XML 文档的结构有深入的了解。
采纳答案by vsingh
This is the solution using itext . Your html content is in the request. And itext is not free. Check out its licensing requirement as it has changed in recent years although it is not very expensive.
这是使用 itext 的解决方案。您的 html 内容在请求中。而且 itext 不是免费的。查看它的许可要求,因为它近年来发生了变化,尽管它不是很贵。
public class MyPDFGeneratorService {
public byte[] generatePdf(final XhtmlPDFGenerationRequest request) {
try {
ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(this.getDocument(request.getContent()), null);
renderer.layout();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
renderer.createPDF(baos);
return this.toByteArray(baos);
}
catch (Exception e) {
throw new PDFGenerationException(
"Unable to generate PDF.", e);
}
}
private Document getDocument(final String content) {
InputSource is = new InputSource(new BufferedReader(new StringReader(
content)));
return XMLResource.load(is).getDocument();
}
private byte[] toByteArray(final ByteArrayOutputStream baos)
throws IOException {
byte[] bytes = baos.toByteArray();
baos.close();
return bytes;
}
}
回答by javabeangrinder
Just for the sake of giving an example using fop - here you have it. For everyone to be able to follow this I'm using the fop command line tool.
只是为了给出一个使用 fop 的例子 - 在这里你有它。为了让每个人都能够遵循这一点,我正在使用 fop 命令行工具。
The same can easily be performed within Java code and then you don't need to have the xml as a file at any time.
同样可以在 Java 代码中轻松执行,然后您无需随时将 xml 作为文件。
XSLT that produce a PDF
生成 PDF 的 XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template match="/">
<fo:root>
<fo:layout-master-set>
<fo:simple-page-master master-name="content"
page-width="210mm" page-height="297mm" margin="20mm 20mm 20mm 20mm">
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="content">
<fo:flow flow-name="xsl-region-body">
<fo:block>
<xsl:apply-templates />
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
<xsl:template match="@*">
<xsl:text> </xsl:text>
<xsl:value-of select="name()" />
<xsl:text>="</xsl:text>
<xsl:value-of select="." />
<xsl:text>"</xsl:text>
</xsl:template>
<xsl:template match="*">
<xsl:param name="indent">0</xsl:param>
<fo:block margin-left="{$indent}">
<xsl:text><</xsl:text>
<xsl:value-of select="name()" />
<xsl:apply-templates select="@*" />
<xsl:text>></xsl:text>
<xsl:apply-templates>
<xsl:with-param name="indent" select="$indent+10" />
</xsl:apply-templates>
<xsl:text></</xsl:text>
<xsl:value-of select="name()" />
<xsl:text>></xsl:text>
</fo:block>
</xsl:template>
</xsl:stylesheet>
We call this file xml2pdf.xsl
我们称这个文件为 xml2pdf.xsl
Short explanation of the code
代码的简短说明
The template match="/" mainly builds the pdf except for the row which calls the other template match methods or more precise the template match="*".
The template match="" writes the element start and end and calls which in turn calls the template match="@" for each attribute in the element (if any). Finally it calls the
The indent parameter gets increased by 10 for each level the template reaches with the select="$indent+10" attribute in the with-param statement.
模板匹配=“/”主要构建pdf,除了调用其他模板匹配方法或更精确的模板匹配=“*”的行。
模板 match=" " 写入元素开始和结束并调用它依次为元素中的每个属性(如果有)调用模板 match="@"。最后它调用
对于模板在 with-param 语句中使用 select="$indent+10" 属性达到的每个级别,缩进参数增加 10。
Using the code
使用代码
# fop -xsl xml2pdf.xsl -xml sample.xml -pdf result.pdf
回答by gaborsch
Try Googling, there are a number of code snippets. For example: http://www.vogella.com/articles/JavaPDF/article.html
尝试谷歌搜索,有许多代码片段。例如:http: //www.vogella.com/articles/JavaPDF/article.html
I recommend iText rather than FOP, it's faster, less memory-intensive and you have more control over the result.
我推荐 iText 而不是 FOP,它更快,内存占用更少,并且您可以更好地控制结果。