【问题标题】:Howto write Cyrillic characters in jFreeChart with iText如何使用 iText 在 jFreeChart 中编写西里尔字符
【发布时间】:2016-03-08 01:44:01
【问题描述】:

我正在使用 itextpdf (5.1.3) 和 jFree chart (1.0.19) 在 pdf 文档中绘制条形图。

要在我的 pdf 文档中写入一些文本,并在我的条形图中作为标题和图例,我使用了一些 unicode 字符(西里尔文文本)。

因此我使用 FreeSans.ttf 作为字体。

根据 Paulo Soares 的回答和http://downloads.sourceforge.net/jfreechart/jfreechart2pdf-v2.pdf 上的示例,我将测试代码更改为:

package com.mytest.business.report;

import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.io.OutputStream;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.category.DefaultCategoryDataset;


import java.io.BufferedOutputStream;

import java.io.FileOutputStream;
import java.io.IOException;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.DefaultFontMapper;
import com.itextpdf.text.pdf.FontMapper;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfTemplate;
import com.itextpdf.text.pdf.PdfWriter;


/**
 * A simple demonstration showing how to write a chart to PDF format using
 * JFreeChart and iText.
 * <P>
 * You can download iText from http://www.lowagie.com/iText.
 */
public class ChartToPDFDemo1 {

    final static String CP1251_TEST_TEXT = "TEST123 - \u042f \u043b\u044e\u0431\u043b\u044e \u0442\u0435\u0431\u044f - ENDE";
    /**
     * Saves a chart to a PDF file.
     *
     * @param file
     *            The file.
     * @param chart
     *            The chart.
     * @param width
     *            The chart width.
     * @param height
     *            The chart height.
     */
    public static void saveChartAsPDF(File file, JFreeChart chart, int width, int height, FontMapper mapper)
            throws IOException {
        OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
        writeChartAsPDF(out, chart, width, height, mapper);
        out.close();
    }

    /**
     * Writes a chart to an output stream in PDF format.
     *
     * @param out
     *            The output stream.
     * @param chart
     *            The chart.
     * @param width
     *            The chart width.
     * @param height
     *            The chart height.
     */
    public static void writeChartAsPDF(OutputStream out, JFreeChart chart, int width, int height, FontMapper mapper)
            throws IOException {

        Document document = new Document(PageSize.A6, 50, 50, 50, 50);;
        try {
            PdfWriter writer = PdfWriter.getInstance(document, out);
            document.addAuthor("JFreeChart");
            document.addSubject("Demonstration");
            document.open();
            document.add( new Paragraph(CP1251_TEST_TEXT, getFont(8, 0)));
            PdfContentByte cb = writer.getDirectContent();
            PdfTemplate tp = cb.createTemplate(width, height);
            Graphics2D g2 = tp.createGraphics(width, height, mapper);
            Rectangle2D r2D = new Rectangle2D.Double(0, 0, width, height);
            chart.draw(g2, r2D, null);
            g2.dispose();
            cb.addTemplate(tp, 0, 0);
        } catch (DocumentException de) {
            System.err.println(de.getMessage());
        }
        document.close();
    }

    public static com.itextpdf.text.Font getFont(final float size, final int style) {

        final String FONT = MyTest.class.getResource("fonts/FreeSans.ttf").getFile();
        return FontFactory.getFont(FONT, BaseFont.IDENTITY_H, BaseFont.EMBEDDED, size, style);
    }

    public static DefaultFontMapper mapper() {
        DefaultFontMapper mapper = new DefaultFontMapper();
        final String FONT = MyTest.class.getResource("fonts").getFile();
        mapper.insertDirectory(FONT);
        DefaultFontMapper.BaseFontParameters pp = mapper.getBaseFontParameters("FreeSans");
        if (pp != null) {
            pp.encoding = BaseFont.IDENTITY_H;
        }

        return mapper;
    }

    /**
     * Starting point for the demonstration application.
     */
    public static void main(String[] args) {
        try {

            JFreeChart chart = ChartFactory.createStackedBarChart(CP1251_TEST_TEXT, "", "", new DefaultCategoryDataset(),
                    PlotOrientation.VERTICAL, true, false, false);

            final Font newtitleFont = new Font("FreeSans", Font.PLAIN, 10);
            chart.getTitle().setFont(newtitleFont);

            Font font = new Font("FreeSans", Font.PLAIN, 8);
            TextTitle subtitle = new TextTitle(CP1251_TEST_TEXT, font);
            chart.addSubtitle(subtitle);


            // write the chart to a PDF file...
            File fileName = new File("target/test3.pdf");
            saveChartAsPDF(fileName, chart, 400, 300, mapper());
            System.out.println("pdf crated...");
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }
}

这将创建示例 pdf 文件:

我的问题是,我在 JBoss 应用程序中创建了 .pdf。此应用程序服务器无法读取带有“class.getResource()”的文件。 为了解决这个问题,我从流中读取并将字体复制到临时文件中。代码如下:

        final byte[] bytes = IOUtils.toByteArray(MyFontFactory.class.getResourceAsStream("fonts/FreeSans.ttf"));

        // Font (mapper) for JFreeChart...
        // Because the mapper can't handle streams we need to copy file to local tmp folder...
        final File tempFile = File.createTempFile("FreeSans", ".ttf", null);
        final FileOutputStream fos = new FileOutputStream(tempFile);
        fos.write(bytes);
        fos.close();

        mapper = new DefaultFontMapper();
        mapper.insertFile(tempFile);
        final DefaultFontMapper.BaseFontParameters pp = mapper.getBaseFontParameters("FreeSans");
        if (pp != null) {
            pp.encoding = BaseFont.IDENTITY_H;
        }

【问题讨论】:

  • 你可以试试Arial字体吗?
  • 已经用 Arial 试过了,效果一样!关键是,这些西里尔字母是这种字体。否则它不会在 itext 中工作。并且这些字符在 itext 中可见....

标签: java unicode itext jfreechart cyrillic


【解决方案1】:

看看http://downloads.sourceforge.net/jfreechart/jfreechart2pdf-v2.pdf。您必须在 awt 字体和 iText 字体之间创建一个字体映射器。像这样的:

DefaultFontMapper mapper = new DefaultFontMapper();
mapper.insertDirectory("c:/windows/fonts");
DefaultFontMapper.BaseFontParameters pp = mapper.getBaseFontParameters("Arial Unicode MS");
if (pp!=null) {
    pp.encoding = BaseFont.IDENTITY_H;
}

【讨论】:

  • 好发现!最初与版本0.8.1的文档一起发布
  • @PauloSoares:我现在根据您的映射器示例更改了我的示例代码。 (见上文)但西里尔字母仍然不可见。请帮忙...
  • 好的。我解决了我的问题。问题是使用 JBoss 从文件中读取...(见上文)
猜你喜欢
  • 1970-01-01
  • 2017-04-19
  • 1970-01-01
  • 2021-11-16
  • 2011-12-06
  • 1970-01-01
  • 1970-01-01
  • 2016-06-15
  • 1970-01-01
相关资源
最近更新 更多