如何在iText pdf中旋转JFreeChart

时间:2012-12-13 16:28:56

标签: java pdf awt itext jfreechart

我创建了一个servlet来处理JSP中显示的JFreeChart到PDF文件的保存。 我到目前为止使用的代码是:

import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jfree.chart.JFreeChart;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.DefaultFontMapper;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfTemplate;
import com.lowagie.text.pdf.PdfWriter;

public class ChartPrintServlet extends HttpServlet {

    private static final long serialVersionUID = -2445101551756014281L;

    protected void doPost ( HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        JFreeChart jFreeChart = (JFreeChart) request.getSession().getAttribute("jFreeChart");
        String url = "";
        int height = 1024;
        int width = 1152;

        if (jFreeChart == null) 
        {
            url = "/do/error";
            RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(url);
            dispatcher.forward(request, response);
        }
        else
        {

            AbsencesGanttChartPostProcessor postProc = new AbsencesGanttChartPostProcessor();
            postProc.processChart(jFreeChart, null);
            response.setContentType("application/pdf");
            response.setHeader("Content-Disposition", "attachment; filename=\"absences.pdf\"");
            OutputStream out = response.getOutputStream();

            try
            {   
                Rectangle pagesize = new Rectangle(width, height);
                Document document = new Document(pagesize.rotate(), 30, 30, 30, 30);
                PdfWriter writer = PdfWriter.getInstance(document, out);
                document.open();
                PdfContentByte cb = writer.getDirectContent();
                PdfTemplate tp = cb.createTemplate(height, width);
                Graphics2D g2 = tp.createGraphics(height, width, new DefaultFontMapper());

                Rectangle2D r2D = new Rectangle2D.Double(0, 0, height, width);
                jFreeChart.draw(g2, r2D);
                g2.dispose();
                cb.addTemplate(tp, 0, 0);
                document.close();
            }
            catch (DocumentException de) 
            {
                System.err.println(de.getMessage());
            }
            finally
            {
                out.close();
            }
        }
    }

    protected void doGet ( HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        doPost(request, response);
    }
}

我已经将高度和宽度交换到各处,以使PDF看起来不太合适,但我真正想要的是能够像横向模式一样创建PDF。

如果我尝试

Graphics2D g2 = tp.createGraphics(height, width, new DefaultFontMapper());
g2.rotate(90)

然后PDF只打印一个白色的空白页。

使用itext / Java awt API在创建PDF时旋转整个文档(包括下面的JFreeChart)的正确方法是什么?

2 个答案:

答案 0 :(得分:2)

首先:你在代码中引用我的名字。我希望您使用itextpdf代替。见http://lowagie.com/itext2

现在提出你的问题。有一种简单的方法可以实现你想要的,而且这种方式更难。

您只在此方法中使用三个参数:cb.addTemplate(tp, 0, 0);这意味着您只需要iText进行翻译(零向上,零向右)。如果您还想要旋转,则需要使用具有七个参数的方法,其中六个参数定义变换矩阵。这是一个简单的代数;它已在我的书" iText in Action"中解释过,但我认识的大多数开发人员都不喜欢做数学,他们说这是困难的方法。

简单的方法是将tp包装在Image对象中,然后旋转图像:

Image img = Image.getInstance(tp);
img.setRotationDegrees(90);

还有setRotation()方法,它将弧度作为参数。

附加说明:

  1. 不要担心Image类栅格化您的内容。包含在PdfTemplate对象中的Image将生成一个Form XObject,它不会被更改为Image XObject。
  2. 小心不要在页面外旋转图像'。您可能需要考虑支点。

答案 1 :(得分:1)

围绕左上角逆时针旋转图形,这样做会将所有内容移出绘图区域。这就是你得到空白页面的原因。您还需要应用翻译以将图形切换回绘画区域。将y向下平移到图像的宽度:

        g.rotate(Math.PI / 2);
        g.translate(0, width);

此外,Graphics2D.rotate需要弧度,而非度数。

之后,如果您为其转换了转换后的Graphics2D,JFreeChart应该绘制转换后的图表。