Viral Patel's tutorial有关如何合并和拆分 PDF 文件的信息很有用。不幸的是,我需要的不仅仅是合并文件,而是将一个 PDF 附加到另一个 PDF。
我正在生成报告,其中一个组件是使用 JFreeChart 绘制的图表秒。我制作的图表被转换为 PDF 并通过合并代码再次读取。假设我有用于文本和表格 PDF 的 main.pdf
和用于后者的 chart.pdf
。
我确定 main.pdf
有一个额外的空间,另一个图形可以放入其中 chart.pdf
我希望后者被缩放并放置在那里而不会在另一个页面中膨胀。
我有下面的代码,但我似乎无法实现它:
创建
chart.pdf
的代码import java.awt.Color; import java.awt.Graphics2D; import java.awt.Paint; import java.awt.geom.Rectangle2D; import java.io.FileOutputStream; import org.jfree.chart.ChartFactory; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.plot.CategoryPlot; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.renderer.category.BarRenderer; import org.jfree.chart.renderer.category.CategoryItemRenderer; import org.jfree.data.category.DefaultCategoryDataset; import com.lowagie.text.Document; 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 ChartDemo { public static void main(String[] args) { writeChartToPDF(generateBarChart(), 500, 400, "D://chart.pdf"); } public static void writeChartToPDF(JFreeChart chart, int width, int height, String fileName) { PdfWriter writer = null; Document document = new Document(new Rectangle(width, height)); try { writer = PdfWriter.getInstance(document, new FileOutputStream( fileName)); document.open(); PdfContentByte contentByte = writer.getDirectContent(); PdfTemplate template = contentByte.createTemplate(width, height); Graphics2D graphics2d = template.createGraphics(width, height, new DefaultFontMapper()); Rectangle2D rectangle2d = new Rectangle2D.Double(0, 0, width, height); chart.draw(graphics2d, rectangle2d); graphics2d.dispose(); contentByte.addTemplate(template, 0, 0); } catch (Exception e) { e.printStackTrace(); } document.close(); } public static JFreeChart generateBarChart() { DefaultCategoryDataset dataSet = new DefaultCategoryDataset(); dataSet.setValue(100, "Population", "2"); dataSet.setValue(78, "Population", "4"); dataSet.setValue(62, "Population", "6"); dataSet.setValue(50, "Population", "8"); dataSet.setValue(39, "Population", "10"); JFreeChart chart = ChartFactory.createBarChart("", "Team number", "Solved problems (%)", dataSet, PlotOrientation.VERTICAL, false, true, false); chart.setBackgroundPaint(Color.WHITE); final CategoryPlot plot = chart.getCategoryPlot(); plot.setBackgroundPaint(Color.WHITE); plot.setDomainGridlinePaint(new Color(204, 204, 204)); plot.setRangeGridlinePaint(new Color(204, 204, 204)); final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis(); rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); final BarRenderer renderer1 = (BarRenderer) plot.getRenderer(); renderer1.setDrawBarOutline(false); renderer1.setShadowVisible(false); renderer1.setDrawBarOutline(false); renderer1.setSeriesPaint(0, Color.gray); renderer1.setSeriesPaint(1, Color.RED); return chart; } }
合并代码
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import com.lowagie.text.Document; import com.lowagie.text.pdf.BaseFont; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.PdfImportedPage; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfWriter; public class MergePdf { public static void main(String[] args) { try { List<InputStream> pdfs = new ArrayList<InputStream>(); pdfs.add(new FileInputStream("D:\\main.pdf")); pdfs.add(new FileInputStream("D:\\chart.pdf")); OutputStream output = new FileOutputStream("D:\\merge.pdf"); MergePdf.concatPDFs(pdfs, output, true); } catch (Exception e) { e.printStackTrace(); } } public static void concatPDFs(List<InputStream> streamOfPDFFiles, OutputStream outputStream, boolean paginate) { Document document = new Document(); try { List<InputStream> pdfs = streamOfPDFFiles; List<PdfReader> readers = new ArrayList<PdfReader>(); int totalPages = 0; Iterator<InputStream> iteratorPDFs = pdfs.iterator(); // Create Readers for the pdfs. while (iteratorPDFs.hasNext()) { InputStream pdf = iteratorPDFs.next(); PdfReader pdfReader = new PdfReader(pdf); readers.add(pdfReader); totalPages += pdfReader.getNumberOfPages(); } // Create a writer for the outputstream PdfWriter writer = PdfWriter.getInstance(document, outputStream); document.open(); BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED); PdfContentByte cb = writer.getDirectContent(); // Holds the PDF // data PdfImportedPage page; int currentPageNumber = 0; int pageOfCurrentReaderPDF = 0; Iterator<PdfReader> iteratorPDFReader = readers.iterator(); // Loop through the PDF files and add to the output. while (iteratorPDFReader.hasNext()) { PdfReader pdfReader = iteratorPDFReader.next(); // Create a new page in the target for each source page. while (pageOfCurrentReaderPDF < pdfReader.getNumberOfPages()) { document.newPage(); pageOfCurrentReaderPDF++; currentPageNumber++; page = writer.getImportedPage(pdfReader, pageOfCurrentReaderPDF); cb.addTemplate(page, 0, 0); // Code for pagination. if (paginate) { cb.beginText(); cb.setFontAndSize(bf, 9); cb.showTextAligned(PdfContentByte.ALIGN_CENTER, "" + currentPageNumber + " of " + totalPages, 520, 5, 0); cb.endText(); } } pageOfCurrentReaderPDF = 0; } outputStream.flush(); document.close(); outputStream.close(); } catch (Exception e) { e.printStackTrace(); } finally { if (document.isOpen()) document.close(); try { if (outputStream != null) outputStream.close(); } catch (IOException ioe) { ioe.printStackTrace(); } } } }
最佳答案
我的回答并没有直接回答你的问题,但它涵盖了你想要的输出——有一个 JFreeChart
图表 within 一个 iText
PDF。
我看到了这个关于如何使用 JFreeChart
制作 iText
PDF 的惊人的现场教程:WireLust's "Creating an iText pdf with embedded JFreeChart" .请注意,这使用了 servlet,我将其修改为只是一个独立的代码,使用 iText
和 JFreeCharts
来处理。
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.io.FileOutputStream;
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.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.DefaultFontMapper;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfTemplate;
import com.itextpdf.text.pdf.PdfWriter;
/**
* Approaching Pi, Inc. http://www.approachingpi.com
* <p/>
* User: tcurran Date: Mar 17, 2008 Time: 2:29:43 AM Desc:
*/
public class PdfChartDemo {
public static void main(String[] args) throws DocumentException {
try {
Document doc = new Document(PageSize.A4);
PdfWriter docWriter = PdfWriter.getInstance(doc,
new FileOutputStream("D:/helix-fossil.pdf"));
doc.open();
doc.addProducer();
doc.addCreator("Jay Leno");
doc.addTitle("jfreechart pdf");
doc.setPageSize(PageSize.LETTER);
doc.open();
// add some text to the document
doc.add(new Phrase(
"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod "
+ "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, "
+ "quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. "
+ "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu "
+ "fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, "
+ "sunt in culpa qui officia deserunt mollit anim id est laborum."));
// build up the dataset for the chart
XYSeriesCollection dataset = new XYSeriesCollection();
XYSeries series = new XYSeries("XYGraph");
series.add(1, 1);
series.add(2, 3);
series.add(3, 9);
series.add(4, 11);
dataset.addSeries(series);
// set up the chart
JFreeChart chart = ChartFactory.createXYLineChart(
"XY Chart Sample, non default font", // chart title
"x-axis", // domain axis label
"y-axis", // range axis label
dataset, // data
PlotOrientation.VERTICAL, // orientation
true, // include legend
true, // tooltips
false // urls
);
// trick to change the default font of the chart
chart.setTitle(new TextTitle("XY Chart Sample, non default font",
new java.awt.Font("Serif", Font.BOLD, 12)));
chart.setBackgroundPaint(Color.white);
chart.setBorderPaint(Color.black);
chart.setBorderStroke(new BasicStroke(1));
chart.setBorderVisible(true);
int width = 260;
int height = 250;
// get the direct pdf content
PdfContentByte dc = docWriter.getDirectContent();
// get a pdf template from the direct content
PdfTemplate tp = dc.createTemplate(width, height);
// create an AWT renderer from the pdf template
Graphics2D g2 = tp.createGraphics(width, height,
new DefaultFontMapper());
Rectangle2D r2D = new Rectangle2D.Double(0, 0, width, height);
chart.draw(g2, r2D, null);
g2.dispose();
// add the rendered pdf template to the direct content
// you will have to play around with this because the chart is
// absolutely positioned.
// 38 is just a typical left margin
// docWriter.getVerticalPosition(true) will approximate the position
// that the content above the chart ended
dc.addTemplate(tp, 38, docWriter.getVerticalPosition(true) - height);
doc.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
它将生成与 servlet 版本相同的 PDF 文件。
关于java - 在另一个 PDF 文件的可用空间附加 PDF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21899463/