2
votes

I'm trying to convert an XML file to PDF using XSLT and XSL-FO/FOP. it works for English characters but for Japanese and Turkish characters like ı,ş etc. it shows # instead of respective character. And also tried different encoding UTF-8, ISO-8859-9 etc. but this did not helped me.

any help will be greatly appreciated.

Thanks!

2

2 Answers

2
votes

From your description, it looks like you are missing japanese and Turkish fonts and you need to add them in your application. You can find general information on how fop handles missing fonts and on how to add more fonts in the following link: https://xmlgraphics.apache.org/fop/trunk/fonts.html

What you need to do is the following:

Assuming you have your font files with the accompanying metrics xml files in a directory, you need to register the fonts in your fop configuration:

This is a sample configuration file (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>

After that, you need to include this config file as well as the fonts in the initialization of your fop factory:

Lets say you have a java class (spring bean) where you use fop:

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();
        }
    }
    }
}
0
votes

What fonts are configured for the FOP engine and what fonts are you using in the document for the text that contains the characters? To render text in a specific language you need:

(1) source data encoded with the proper characters

(2) XSL/XSL FO that references a font for those characters which actually contains the glyphs for those characters

(3) The specific fonts you are using referenced so that the application you are using is aware of them.

It sounds like you have an issue in either (2) or (3)

You have either not referenced the correct font in the XSL FO (like you are using Helvetica to format Chinese and Helvetica does not contain Chinese glyphs).

Or possibly you are referencing the correct font XSL FO but have not set up Apache FOP to find that font.