使用XSLT和XSL-FO / FOP将XML文件转换为PDF

时间:2015-01-22 06:31:49

标签: java xslt xsl-fo apache-fop

我正在尝试使用XSLT和XSL-FO / FOP将XML文件转换为PDF。它适用于英文字符,但对于日语和土耳其字符,如ı,ş等,它显示#而不是各自的字符。 并尝试了不同的编码UTF-8,ISO-8859-9等,但这对我没有帮助。

任何帮助将不胜感激。

谢谢!

2 个答案:

答案 0 :(得分:2)

根据您的描述,您似乎缺少日语和土耳其语字,您需要在应用程序中添加它们。 您可以在以下链接中找到有关fop如何处理丢失字体以及如何添加更多字体的一般信息: https://xmlgraphics.apache.org/fop/trunk/fonts.html

您需要做的是:

假设您的字体文件包含目录中附带的指标xml文件,则需要在fop配置中注册字体:

这是一个示例配置文件(fopUserConfig.xml):

<?xml version="1.0" encoding="UTF-8"?>
<fop version="1.0">
    <renderers>
        <renderer mime="application/pdf">
            <fonts>
                <font metrics-url="verdana.xml" kerning="yes"
                    embed-url="VERDANA.TTF">
                    <font-triplet name="Verdana" style="normal" weight="normal" />
                </font>
                <font metrics-url="verdanab.xml" kerning="yes"
                    embed-url="VERDANAB.TTF">
                    <font-triplet name="Verdana-Bold" style="normal" weight="bold" />
                </font>
                <font metrics-url="verdanai.xml" kerning="yes"
                    embed-url="VERDANAI.TTF">
                    <font-triplet name="Verdana-Italic" style="italic" weight="normal" />
                </font>
                <font metrics-url="verdanaz.xml" kerning="yes"
                    embed-url="VERDANAZ.TTF">
                    <font-triplet name="Verdana-BoldItalic" style="italic" weight="bold" />
                </font>             
            </fonts>
        </renderer>
    </renderers>
</fop>

之后,您需要在fop工厂的初始化中包含此配置文件以及字体:

假设你有一个使用fop的java类(spring bean):

public class PdfReportGenerator {

    /**
    * Reference to pdfReportTransformer.xsl
    */
    @Value("classpath:templates/pdfReportTransformer.xsl")
    private Resource basePathRef;

    @Value("classpath:templates/fopUserConfig.xml")
    private Resource fopConfiguration;

    @Value("classpath:templates/fonts/VERDANA.TTF")
    private Resource fontBase;

    public void doPdfTransformation(String xmlInput, File xslFOInput, File outputPDf) throws TransformerException,
            IOException {

     // Step 1: Construct a FopFactory
            // (reuse if you plan to render multiple documents!)
            FopFactory fopFactory = FopFactory.newInstance();
            OutputStream out = null;

            try {
                // add the user configuration needed in order to embed the fonts in
                // the pdf.
                fopFactory.setUserConfig(fopConfiguration.getFile());
                fopFactory.setBaseURL(basePathRef.getFile().getParentFile().getCanonicalPath());
                FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
                foUserAgent.setBaseURL(fopFactory.getBaseURL());

                fopFactory.getFontManager().setFontBaseURL(fontBase.getFile().getParentFile().getCanonicalPath());

      ...
    }
    catch (SAXException e) {
        LOGGER.error("Error While initializing fop", e);
    }
    finally {
        // Clean-up
        if (out != null) {
            out.close();
        }
    }
    }
}

答案 1 :(得分:0)

为FOP引擎配置了哪些字体,以及您在文档中使用哪些字体包含字符?要以您需要的特定语言呈现文本:

(1)用适当的字符编码的源数据

(2)XSL / XSL FO引用那些实际包含这些字符的字形的字符的字体

(3)您使用的特定字体被引用,以便您使用的应用程序知道它们。

听起来你在(2)或(3)

中都有问题

您没有在XSL FO中引用正确的字体(就像您使用Helvetica格式化中文而Helvetica不包含中文字形)。

或者您可能正在引用正确的字体XSL FO,但尚未设置Apache FOP来查找该字体。