我有一个XML文档,当前存储为内存中的字符串&想要将其渲染为PDF。换句话说,PDF内容将是XML文档。该方法呈现的XML是通用的 - 可能会发送多种类型的XML文档。
我很难弄清楚如何使用各种基于Java的框架来完成使用。
Apache FOP
好像这个框架需要将文档中的XML元素特定转换为FOP实体。由于问题中的方法必须接受通用XML,我认为这个框架不符合我的要求。
iText的
我尝试使用iText / Flying Saucer(org.xhtmlrenderer)的组合渲染文档,虽然它确实渲染了PDF,但内容只包含空格分隔的数据值,没有xml元素或属性。使用代码&测试数据如下:
文件
<?xml version="1.0" encoding="UTF-8"?>
<root>
<elem1>value1</elem1>
<elem2>value2</elem2>
</root>
代码
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();
包含内容值value1 value2
但没有标记的PDF格式的结果。
我的问题是 有人可以提供一个代码片段,用于使用上面的一个框架来重新发送包含XML内容的PDF,还是有另一个框架更适合我的需求?
修改 我意识到同样的问题被问到here,但似乎所提出的解决方案需要对css文件中传入的XML文档的结构有深入的了解。
答案 0 :(得分:3)
只是为了给出一个使用fop的例子 - 在这里你有它。为了让每个人都能够遵循这一点,我正在使用fop命令行工具。
在Java代码中可以轻松执行相同的操作,然后您无需随时将xml作为文件。
<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>
我们将此文件称为xml2pdf.xsl
模板匹配=“/”主要构建pdf,除了调用其他模板匹配方法的行或更精确的模板匹配=“*”。
模板匹配=“”写入元素的开始和结束,并调用元素中的每个属性(如果有的话)调用模板match =“@ ”。最后它调用了
对于模板在with-param语句中使用select =“$ indent + 10”属性到达的每个级别,indent参数增加10。
# fop -xsl xml2pdf.xsl -xml sample.xml -pdf result.pdf
答案 1 :(得分:2)
尝试谷歌搜索,有很多代码片段。例如:http://www.vogella.com/articles/JavaPDF/article.html
我推荐iText而不是FOP,它更快,内存更少,你可以更好地控制结果。
答案 2 :(得分:2)
这是使用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;
}
}