减小iText生成的PDF的大小,包括时间序列条形图

时间:2014-01-31 17:49:35

标签: itext jfreechart

为PDF中的较长时间跨度添加时间序列条形图会导致文件大小(如50 MB或更大),具体取决于数据点。以下是代码示例:

将图表添加到PDF

Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(RESULT));
document.open();
PdfContentByte cb = writer.getDirectContent();
float width = PageSize.A4.getWidth();
float height = PageSize.A4.getHeight() / 2;

PdfTemplate bar = cb.createTemplate(width, height);
Graphics2D g2d2 = new PdfGraphics2D(bar, width, height);
Rectangle2D r2d2 = new Rectangle2D.Double(0, 0, width, height);
getBarChart().draw(g2d2, r2d2);
g2d2.dispose();
cb.addTemplate(bar, 0, 0);
document.close();

创建图表

JFreeChart getBarChart() {
    TimeSeries series = new TimeSeries("Data");

    GregorianCalendar cal = new GregorianCalendar();
    for (int i=0; i<365*24; i++) {
        cal.add(Calendar.HOUR, 1);
        series.addOrUpdate(new Millisecond(cal.getTime()), Math.random());
    }

    XYPlot plot = new XYPlot();
    plot.setDataset(new XYBarDataset(new TimeSeriesCollection(series), 10));
    plot.setRenderer(new XYBarRenderer());
    plot.setRangeAxis(new NumberAxis());
    plot.setDomainAxis(new DateAxis());

    return new JFreeChart(plot);
}

如何减小文件大小?

使用itextpdf-5.4.4和jfreechart-1.0.15。

2 个答案:

答案 0 :(得分:1)

在检查OP提供的PDF时,很快就会发现它充满了用于绘制漂亮条形图的 Pattern 定义等。因此,为了减小PDF尺寸,可以简化条形设计。

在手头的情况下,可以通过设置不同的默认条形画家(使用XYBarRenderer.setDefaultBarPainter())来完成。该属性的初始值为GradientXYBarPainter,但对于如此小的条形使用渐变会使所需的绘制操作和操作符的数量爆炸,而只会在巨大的缩放级别上产生差异(如果有的话)。

正如问题评论中已经解决的那样,使用StandardXYBarPainter来解决尺寸问题。

答案 1 :(得分:0)

您可以尝试设置完全压缩并比较差异:

PdfReader reader = new PdfReader(new FileInputStream("in.pdf"));
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("out.pdf"));
int total = reader.getNumberOfPages() + 1;
for ( int i=1; i<total; i++) {
    reader.setPageContent(i + 1, reader.getPageContent(i + 1));
}
stamper.setFullCompression();
stamper.close();