I want to draw a xy line chart on PDF. After clicking on a button on a JSP, a PDF will be generated with xy line chart. So I have used jfreechart to create xy line chart and then wants to print it in PDF format using OrsonPDF.
I have seen the same example on https://jfree.github.io/orsonpdf/
But the problem is I couldn't run it using server request, response. And also the code itself gives some error.
The button code is as below:
<form action="testPdf" method="post" target="_blank">
<center><button class="submitbtn" value="submit" type="submit"><center>Generate PDF</center></button></center>
</form>
Here I am attaching my 'testPdf.java' code:
package servlet;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Rectangle;
import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.xobject.PdfFormXObject;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Image;
import com.itextpdf.layout.element.Paragraph;
import com.orsonpdf.PDFDocument;
import com.orsonpdf.PDFGraphics2D;
import com.orsonpdf.Page;
import com.itextpdf.text.Element;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Font.FontFamily;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.block.BlockBorder;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.chart.title.TextTitle;
import org.jfree.chart.ui.HorizontalAlignment;
import org.jfree.data.time.Month;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYDataset;
/**
* Creates a PDF document with iText, then inserts a PDF chart generated with
* JFreeChart and OrsonPDF.
*/
public class testPdf extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
static final long serialVersionUID = 1L;
/* (non-Java-doc)
* @see javax.servlet.http.HttpServlet#HttpServlet()
*/
public testPdf() {
super();
}
private static byte[] generateChartPDF() {
// here we use OrsonPDF to generate PDF in a byte array
PDFDocument doc = new PDFDocument();
Rectangle bounds = new Rectangle(500, 335);
Page page = doc.createPage(bounds);
PDFGraphics2D g2 = page.getGraphics2D();
JFreeChart chart = createChart(createDataset());
chart.draw(g2, bounds);
return doc.getPDFBytes();
}
/**
* Creates a chart.
*
* @param dataset a dataset.
*
* @return A chart.
*/
private static JFreeChart createChart(XYDataset dataset) {
JFreeChart chart = ChartFactory.createTimeSeriesChart(
"International Coffee Organisation : Coffee Prices",
null, "US cents/lb", dataset);
String fontName = "Serif";
chart.getTitle().setFont(new Font(fontName, Font.BOLD, 18));
chart.addSubtitle(new TextTitle(
"Source: http://www.ico.org/historical/2010-19/PDF/HIST-PRICES.pdf",
new Font(fontName, Font.PLAIN, 14)));
XYPlot plot = (XYPlot) chart.getPlot();
plot.setDomainPannable(true);
plot.setRangePannable(false);
plot.setDomainCrosshairVisible(true);
plot.setRangeCrosshairVisible(true);
plot.getDomainAxis().setLowerMargin(0.0);
plot.getDomainAxis().setLabelFont(new Font(fontName, Font.BOLD, 14));
plot.getDomainAxis().setTickLabelFont(new Font(fontName, Font.PLAIN, 10));
plot.getRangeAxis().setLabelFont(new Font(fontName, Font.BOLD, 14));
plot.getRangeAxis().setTickLabelFont(new Font(fontName, Font.PLAIN, 10));
plot.setRangeGridlinePaint(Color.GRAY);
plot.setDomainGridlinePaint(Color.GRAY);
chart.getLegend().setItemFont(new Font(fontName, Font.PLAIN, 14));
chart.getLegend().setFrame(BlockBorder.NONE);
chart.getLegend().setHorizontalAlignment(HorizontalAlignment.CENTER);
XYItemRenderer r = plot.getRenderer();
if (r instanceof XYLineAndShapeRenderer) {
XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) r;
renderer.setDefaultShapesVisible(false);
renderer.setDrawSeriesLineAsPath(true);
// set the default stroke for all series
renderer.setAutoPopulateSeriesStroke(false);
renderer.setDefaultStroke(new BasicStroke(3.0f,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL), false);
renderer.setSeriesPaint(0, Color.RED);
renderer.setSeriesPaint(1, new Color(24, 123, 58));
renderer.setSeriesPaint(2, new Color(149, 201, 136));
renderer.setSeriesPaint(3, new Color(1, 62, 29));
renderer.setSeriesPaint(4, new Color(81, 176, 86));
renderer.setSeriesPaint(5, new Color(0, 55, 122));
renderer.setSeriesPaint(6, new Color(0, 92, 165));
}
return chart;
}
/**
* Creates a dataset, consisting of two series of monthly data.
*
* @return the dataset.
*/
private static XYDataset createDataset() {
TimeSeries s1 = new TimeSeries("Indicator Price");
s1.add(new Month(1, 2010), 126.80);
s1.add(new Month(2, 2010), 123.37);
s1.add(new Month(3, 2010), 125.30);
s1.add(new Month(4, 2010), 126.89);
s1.add(new Month(5, 2010), 128.10);
s1.add(new Month(6, 2010), 142.20);
s1.add(new Month(7, 2010), 153.41);
s1.add(new Month(8, 2010), 157.46);
s1.add(new Month(9, 2010), 163.61);
s1.add(new Month(10, 2010), 161.56);
TimeSeries s2 = new TimeSeries("Columbian Milds");
s2.add(new Month(1, 2010), 207.51);
s2.add(new Month(2, 2010), 204.71);
s2.add(new Month(3, 2010), 205.71);
s2.add(new Month(4, 2010), 200.00);
s2.add(new Month(5, 2010), 200.54);
s2.add(new Month(6, 2010), 224.49);
s2.add(new Month(7, 2010), 235.52);
s2.add(new Month(8, 2010), 243.98);
s2.add(new Month(9, 2010), 247.77);
s2.add(new Month(10, 2010), 230.02);
TimeSeries s3 = new TimeSeries("Other Milds");
s3.add(new Month(1, 2010), 158.90);
s3.add(new Month(2, 2010), 157.86);
s3.add(new Month(3, 2010), 164.50);
s3.add(new Month(4, 2010), 169.55);
s3.add(new Month(5, 2010), 173.38);
s3.add(new Month(6, 2010), 190.90);
s3.add(new Month(7, 2010), 203.21);
s3.add(new Month(8, 2010), 211.59);
s3.add(new Month(9, 2010), 222.71);
s3.add(new Month(10, 2010), 217.64);
TimeSeriesCollection dataset = new TimeSeriesCollection();
dataset.addSeries(s1);
dataset.addSeries(s2);
dataset.addSeries(s3);
return dataset;
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletOutputStream os = response.getOutputStream();
response.setContentType("application/pdf");
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, os);
PdfDocument targetPDF = new PdfDocument(writer);
document.add(new Paragraph("Demo showing a JFreeChart being rendered into a PDF document created by iText 7."));
PdfReader reader = new PdfReader(new ByteArrayInputStream(generateChartPDF()));
PdfDocument chartDoc = new PdfDocument(reader);
PdfFormXObject chart = chartDoc.getFirstPage().copyAsFormXObject(targetPDF);
Image chartImage = new Image(chart);
document.add(new Paragraph("Here we add a chart... ").add(chartImage));
document.close();
}
/* (non-Java-doc)
* @see javax.servlet.http.HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
Please help me to find the solution. I cannot solve this problem from last couple of days. I know its a very common problem although, but couldn't find any solution. Thank you in advance.