Java 如何在iText pdf中旋转JFreeChart

Java 如何在iText pdf中旋转JFreeChart,java,pdf,awt,itext,jfreechart,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.ServletExcep

我创建了一个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只打印一个白色的空白页面


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

围绕左上角逆时针旋转图形,这样做会将所有内容移出绘图区域。这就是为什么你只得到空白页。您还需要应用平移来将图形移回绘制区域。将y向下平移图像的宽度:

        g.rotate(Math.PI / 2);
        g.translate(0, width);
此外,期望的是弧度,而不是度


之后,如果您将转换后的图形2d传递给JFreeChart,则JFreeChart应该绘制转换后的图表。

您可以围绕左上角逆时针旋转图形,这样做会将所有内容移出绘图区域。这就是为什么你只得到空白页。您还需要应用平移来将图形移回绘制区域。将y向下平移图像的宽度:

        g.rotate(Math.PI / 2);
        g.translate(0, width);
此外,期望的是弧度,而不是度


之后,如果您将转换后的图形2d传递给JFreeChart,则JFreeChart应该绘制转换后的图表。

首先,您需要在代码中引用我的名字。我希望你改用itextpdf。看

现在回答你的问题。有一个简单的方法来实现你想要的,还有一个更困难的方法

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

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

Image img = Image.getInstance(tp);
img.setRotationDegrees(90);
还有一个
setRotation()
方法将弧度作为参数

补充说明:

  • 不要担心图像类会使内容光栅化。包装在
    图像
    对象中的
    PdfTemplate
    将生成一个表单XObject,它不会被更改为图像XObject
  • 注意不要将图像旋转到“页面外”。您可能需要考虑轴心点

  • 首先,你在代码中引用我的名字。我希望你改用itextpdf。看

    现在回答你的问题。有一个简单的方法来实现你想要的,还有一个更困难的方法

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

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

    Image img = Image.getInstance(tp);
    img.setRotationDegrees(90);
    
    还有一个
    setRotation()
    方法将弧度作为参数

    补充说明:

  • 不要担心图像类会使内容光栅化。包装在
    图像
    对象中的
    PdfTemplate
    将生成一个表单XObject,它不会被更改为图像XObject
  • 注意不要将图像旋转到“页面外”。您可能需要考虑轴心点

  • 感谢您的有益评论,但是底层图像似乎没有改变。我用一些截图粘贴了上面修改过的代码。丢失的项目是其中的一部分,因为。好的,我找到了它们,但现在问题更不清楚了。我对编辑的解释是:Bizmark创建了一个宽度为X、高度为Y的图表。他似乎希望在旋转图表时完全重新绘制图表。这没有多大意义,我倾向于在没有进一步澄清的情况下否决这个问题。嗯,是的,我正在寻找一种方法来重新绘制它,为什么还要在图形上调用旋转?基本上,我希望创建PDF时,图表最初以纵向显示(在浏览器中)时,它就像在横向中一样,这样用户就不必在横向中打印它,也不必在打开PDF后以其他方式修改布局。感谢您提供的有用意见,但是底层图像似乎没有改变。我用一些截图粘贴了上面修改过的代码。丢失的项目是其中的一部分,因为。好的,我找到了它们,但现在问题更不清楚了。我对编辑的解释是:Bizmark创建了一个宽度为X、高度为Y的图表。他似乎希望在旋转图表时完全重新绘制图表。这没有多大意义,我倾向于在没有进一步澄清的情况下否决这个问题。嗯,是的,我正在寻找一种方法来重新绘制它,为什么还要在图形上调用旋转?基本上,我希望创建PDF时,图表最初显示(在浏览器中)为纵向时,它就像在横向中一样,这样用户就不必在横向中打印它,也不必在打开PDF后摆弄布局。这可能是因为您将图像旋转到了模板的可见区域之外。我想如果你在一个工具中打开PDF,你会看到绘制图表的语法,这个工具可以让你看到内容流。还请记住,如果要在某处写入旋转/平移图像,则必须切换高度和宽度尺寸i