Как написать кириллицу в jFreeChart с помощью iText
Я использую itextpdf (5.1.3) и диаграмму jFree (1.0.19), чтобы нарисовать гистограмму внутри документа PDF.
Чтобы написать текст в моем документе PDF, а также в качестве заголовка и легенды в моей гистограмме, я использую некоторые символы Юникода (кириллический текст).
Поэтому я использую FreeSans.ttf в качестве шрифта.
Согласно ответу Пауло Соареш и примера на 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:
Моя проблема была, я создал. PDF в моем приложении JBoss. Этот сервер приложений не может прочитать файл с помощью "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;
}
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;
}