I've created a document with some Chapters.
How to generate a TOC for this document?
It should look like this:
TOC:
Chapter 1 3
Chapter 2 4
Chapter 3 6
Chapter 4 9
Chapter 5 10
This is possible by using PdfTemplates. PdfTemplates are a kind of placeholder that you can fill afterwards.
Update with the hints from Bruno:
To generate at TOC at the beginning, you need to put some Placeholders for all the page numbers in the TOC. Those PdfTemplates you collect in a Map. Then, when you add the Chapters to the document, you can fill those placeholders.
This example shows how:
package com.example.main;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.Map;
import com.itextpdf.text.Chapter;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfTemplate;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.draw.VerticalPositionMark;
public class Main extends PdfPageEventHelper {
private final Document document;
private final PdfWriter writer;
private final BaseFont baseFont = BaseFont.createFont();
private final Font chapterFont = FontFactory.getFont(FontFactory.HELVETICA, 24, Font.NORMAL);
// table to store placeholder for all chapters and sections
private final Map<String, PdfTemplate> tocPlaceholder = new HashMap<String, PdfTemplate>();
// store the chapters and sections with their title here.
private final Map<String, Integer> pageByTitle = new HashMap<>();
public static void main(final String[] args) throws Exception {
final Main main = new Main();
main.document.add(new Paragraph("This is an example to generate a TOC."));
main.createTOC(10);
main.createChapters(10);
main.document.close();
}
public Main() throws Exception {
this.document = new Document(PageSize.A6);
this.writer = PdfWriter.getInstance(this.document, new FileOutputStream("test.pdf"));
this.writer.setPageEvent(this);
this.document.open();
}
#Override
public void onChapter(final PdfWriter writer, final Document document, final float paragraphPosition, final Paragraph title) {
this.pageByTitle.put(title.getContent(), writer.getPageNumber());
}
#Override
public void onSection(final PdfWriter writer, final Document document, final float paragraphPosition, final int depth, final Paragraph title) {
this.pageByTitle.put(title.getContent(), writer.getPageNumber());
}
private void createTOC(final int count) throws DocumentException {
// add a small introduction chapter the shouldn't be counted.
final Chapter intro = new Chapter(new Paragraph("This is TOC ", this.chapterFont), 0);
intro.setNumberDepth(0);
this.document.add(intro);
for (int i = 1; i < count + 1; i++) {
// Write "Chapter i"
final String title = "Chapter " + i;
final Chunk chunk = new Chunk(title).setLocalGoto(title);
this.document.add(new Paragraph(chunk));
// Add a placeholder for the page reference
this.document.add(new VerticalPositionMark() {
#Override
public void draw(final PdfContentByte canvas, final float llx, final float lly, final float urx, final float ury, final float y) {
final PdfTemplate createTemplate = canvas.createTemplate(50, 50);
Main.this.tocPlaceholder.put(title, createTemplate);
canvas.addTemplate(createTemplate, urx - 50, y);
}
});
}
}
private void createChapters(final int count) throws DocumentException {
for (int i = 1; i < count + 1; i++) {
// append the chapter
final String title = "Chapter " + i;
final Chunk chunk = new Chunk(title, this.chapterFont).setLocalDestination(title);
final Chapter chapter = new Chapter(new Paragraph(chunk), i);
chapter.setNumberDepth(0);
chapter.addSection("Foobar1");
chapter.addSection("Foobar2");
this.document.add(chapter);
// When we wrote the chapter, we now the pagenumber
final PdfTemplate template = this.tocPlaceholder.get(title);
template.beginText();
template.setFontAndSize(this.baseFont, 12);
template.setTextMatrix(50 - this.baseFont.getWidthPoint(String.valueOf(this.writer.getPageNumber()), 12), 0);
template.showText(String.valueOf(this.writer.getPageNumber()));
template.endText();
}
}
}
The generated PDF looks like this:
TableOfContents.pdf
The answer by Christian Schneider seems somewhat complex. I would also use page event, but I would use the onChapter() method to create a list of chapter titles and page numbers. If you also need Section titles, use the onSection() method to keep track of the sections too.
Once you have this list, create the TOC at the end of the document. If you want to move the TOC to the front, read my answer to this question: PDF Page re-ordering using itext
Related
I have weird problem when I try to use iText 7. Some parts of the PDF are modified (text to change to bold, line weights increase and double points change to hearts). In iText version 5.4.4 this didn't happened, but every version since that I have tried cause this same problem (5 or 7).
Does anyone have a clued why this is happening and is there anything I could to do to bypass this problem? Any help would be appreciated!
If more information is needed, I will try to provide it.
Below is simple code that I used to test iText 7.
Example PDF Files
package javaapplication1;
import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.pdfcleanup.PdfCleanUpLocation;
import com.itextpdf.pdfcleanup.PdfCleanUpTool;
import com.itextpdf.pdfcleanup.autosweep.ICleanupStrategy;
import com.itextpdf.pdfcleanup.autosweep.PdfAutoSweep;
import com.itextpdf.pdfcleanup.autosweep.RegexBasedCleanupStrategy;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
public class JavaApplication1 {
public static final String DEST = "D:/TEMP/TEMP/PDF/result/orientation_result.pdf";
public static final String DEST2 = "D:/TEMP/TEMP/PDF/result/orientation_result2.pdf";
public static final String DEST3 = "D:/TEMP/TEMP/PDF/result/orientation_result3.pdf";
public static final String SRC = "D:/TEMP/TEMP/PDF/TEST_PDF.pdf";
public static void main(String[] args) throws IOException {
File file = new File(DEST);
file.getParentFile().mkdirs();
new JavaApplication1().manipulatePdf(DEST);
new JavaApplication1().manipulatePdf2(DEST2);
try (PdfDocument pdf = new PdfDocument(new PdfReader(SRC), new PdfWriter(DEST3))) {
final ICleanupStrategy cleanupStrategy = new RegexBasedCleanupStrategy(Pattern.compile("2019", Pattern.CASE_INSENSITIVE)).setRedactionColor(ColorConstants.PINK);
final PdfAutoSweep autoSweep = new PdfAutoSweep(cleanupStrategy);
autoSweep.cleanUp(pdf);
} catch (Exception e) {
System.out.println(e.toString());
}
}
protected void manipulatePdf(String dest) throws IOException {
PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(dest));
List<PdfCleanUpLocation> cleanUpLocations = new ArrayList<PdfCleanUpLocation>();
// The arguments of the PdfCleanUpLocation constructor: the number of page to be cleaned up,
// a Rectangle defining the area on the page we want to clean up,
// a color which will be used while filling the cleaned area.
PdfCleanUpLocation location = new PdfCleanUpLocation(1, new Rectangle(97, 405, 383, 40),
ColorConstants.GRAY);
cleanUpLocations.add(location);
PdfCleanUpTool cleaner = new PdfCleanUpTool(pdfDoc, cleanUpLocations);
cleaner.cleanUp();
pdfDoc.close();
}
protected void manipulatePdf2(String dest) throws IOException {
PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(dest));
// If the second argument is true, then regions to be erased are extracted from the redact annotations
// contained inside the given document. If the second argument is false (that's default behavior),
// then use PdfCleanUpTool.addCleanupLocation(PdfCleanUpLocation)
// method to set regions to be erased from the document.
PdfCleanUpTool cleaner = new PdfCleanUpTool(pdfDoc, true);
cleaner.cleanUp();
pdfDoc.close();
}
}
Sorry for late response. I managed now verify that updating to latest versions corrected this problem. Thanks to #mkl pointing this out.
Problem solved
I am working on a project for fun that handles creating my custom letterhead. I'm using Apache POI to handle word documents. I plan on expanding it once I have the base framework done to add a GUI using AWT and allowing for customization through it, which explains how I have some things set up in code. I am getting some really bizarre results when trying to format my header, it appears that Apache POI is inserting newlines where it wants to? I think I am not understanding something.
CreateDocument.java
package letterHeader;
import java.io.File;
import java.io.FileOutputStream;
import java.math.BigInteger;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPageMar;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;
public class CreateDocument
{
// create blank document
static XWPFDocument document = new XWPFDocument();
// create paragraphs for header
static XWPFParagraph name = document.createParagraph();
static XWPFParagraph address = document.createParagraph();
static ArrayList<XWPFParagraph> phoneNumbers = new ArrayList<XWPFParagraph>();
static ArrayList<XWPFParagraph> emails = new ArrayList<XWPFParagraph>();
static XWPFParagraph date = document.createParagraph();
// create runner objects
static XWPFRun nameRunner = name.createRun();
static XWPFRun addressRunner = address.createRun();
// remember to make a runner for each email
static ArrayList<XWPFRun> phoneRunners = new ArrayList<XWPFRun>();
static ArrayList<XWPFRun> emailRunners = new ArrayList<XWPFRun>();
public static void main(String[] args) throws Exception
{
// make datetime for timestamp
DateFormat dateFormat = new SimpleDateFormat("MM:dd:yyyy");
Date date = new Date();
// create IO stream with document name
FileOutputStream out = new FileOutputStream( new File("letterhead" + dateFormat.format(date) + ".docx"));
CTSectPr sectPr = document.getDocument().getBody().addNewSectPr();
CTPageMar pageMar = sectPr.addNewPgMar();
pageMar.setLeft(BigInteger.valueOf(720L));
pageMar.setTop(BigInteger.valueOf(720L));
pageMar.setRight(BigInteger.valueOf(720L));
pageMar.setBottom(BigInteger.valueOf(720L));
// storing the ID automatically makes the objects
int phoneID = addListParagraph("phone");
int emailID1 = addListParagraph("email");
int emailID2 = addListParagraph("email");
// make name
nameRunner.setText("Michael Simanski");
nameRunner.setBold(true);
nameRunner.setFontSize(18);
nameRunner.setFontFamily("Times");
// make address
addressRunner.setText("address");
addressRunner.setFontSize(12);
addressRunner.setFontFamily("Times");
// make phone
phoneRunners.get(phoneID).setText("phone");
phoneRunners.get(phoneID).setFontSize(12);
phoneRunners.get(phoneID).setFontFamily("Times");
// make emails
emailRunners.get(emailID1).setText("mfsimanski#gmail.com");
emailRunners.get(emailID1).setFontSize(12);
emailRunners.get(emailID1).setFontFamily("Times");
emailRunners.get(emailID2).setText("secondemail");
emailRunners.get(emailID2).setFontSize(12);
emailRunners.get(emailID2).setFontFamily("Times");
emailRunners.get(emailID2).addCarriageReturn();
document.write(out);
out.close();
}
public static int addListParagraph(String type)
{
switch (type)
{
case "phone":
phoneNumbers.add(document.createParagraph());
phoneRunners.add(phoneNumbers.get(phoneNumbers.size() - 1).createRun());
return phoneNumbers.size() - 1;
case "email":
emails.add(document.createParagraph());
emailRunners.add(emails.get(emails.size() - 1).createRun());
return emails.size() - 1;
default:
System.out.println("ERROR: Paragraph type not found!");
return 0;
}
}
}
Pretty simple right? I expect the following results:
letterhead07/08/2019.docx
Michael Simanski
address
phone
mfsimanski#gmail.com
secondemail
But perplexingly I get:
letterhead07/08/2019.docx
Michael Simanski
address
phone
mfsimanski#gmail.com
secondemail
Am I missing something, stupid, or both?
I need to generate PDF-documents with java. I've tried with iTextPDF, and with ApachePDFbox. I have the impression, these are libraries to do all possible things with PDF.
But I only have a few requirements:
create a PDF-document from Scratch
add chapters having a title
adding plain text to a chapter
adding text from HTML to a chapter
adding an image to the chapter, being scaled to fit if needed
adding a table to the chapter
create a header and a footer
having a background image
There is quite a learning curve to do these things with the libraries mentioned above. So I'm dreaming of a high level API making my life much easier, having these few methods:
createChapter(String title)
addPlainText(Chapter chapter,String text)
addHtml(Chapter chapter,String html)
addImage(Chapter chapter,byte[] bytes) (because it's coming out of the DB)
addTable(Chapter chapter, TableModel table)
addHeader(HeaderFooterModel header)
addFooter(HeaderFooterModel footer)
addBackGroundImage(Chapter chapter,byte[] bytes)
Is there something like that already available? This would be cool and safe some time.
Following class is a great start at having a very high level API for iText.
I implemented most of the methods you requested.
The remainder is left as a challenge to the reader.
package stackoverflow;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.color.Color;
import com.itextpdf.kernel.color.DeviceRgb;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.IBlockElement;
import com.itextpdf.layout.element.IElement;
import com.itextpdf.layout.element.Image;
import com.itextpdf.layout.element.Paragraph;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ITextForDummiesFacade
{
// iText IO
private PdfDocument pdfDocument;
private Document layoutDocument;
// font sizes
private float regularFontSize = 12f;
private float chapterTitleFontSize = 14f;
// font colors
private Color chapterFontColor = new DeviceRgb(249, 157, 37);
private Color regularFontColor = new DeviceRgb(100, 100, 100);
// structure
private Map<String, Integer> chapterNames = new HashMap<>();
private Map<Integer, List<IElement>> elementsPerChapter = new HashMap<>();
public ITextForDummiesFacade(OutputStream os) throws IOException
{
this.pdfDocument = new PdfDocument(new PdfWriter(os));
this.layoutDocument = new Document(pdfDocument);
}
public ITextForDummiesFacade(File outputFile) throws IOException
{
this.pdfDocument = new PdfDocument(new PdfWriter(outputFile));
this.layoutDocument = new Document(pdfDocument);
}
public boolean createChapter(String title)
{
if(chapterNames.containsKey(title))
return false;
int nextID = chapterNames.size();
chapterNames.put(title, nextID);
elementsPerChapter.put(nextID, new ArrayList<IElement>());
elementsPerChapter.get(nextID).add(new Paragraph(title)
.setFontSize(chapterTitleFontSize)
.setFontColor(chapterFontColor));
return true;
}
public boolean addPlainText(String chapter, String text)
{
if(!chapterNames.containsKey(chapter))
return false;
int ID = chapterNames.get(chapter);
elementsPerChapter.get(ID).add(new Paragraph(text)
.setFontSize(regularFontSize)
.setFontColor(regularFontColor));
return true;
}
public boolean addHTML(String chapter, String HTML)
{
if(!chapterNames.containsKey(chapter))
return false;
int ID = chapterNames.get(chapter);
try
{
elementsPerChapter.get(ID).addAll(HtmlConverter.convertToElements(HTML));
} catch (IOException e)
{
e.printStackTrace();
return false;
}
return true;
}
public boolean addImage(String chapter, byte[] image)
{
if(!chapterNames.containsKey(chapter))
return false;
int ID = chapterNames.get(chapter);
elementsPerChapter.get(ID).add(new Image(ImageDataFactory.create(image)));
return true;
}
private void write()
{
for(int i=0;i<chapterNames.size();i++)
{
for(IElement e : elementsPerChapter.get(i))
if(e instanceof IBlockElement)
layoutDocument.add((IBlockElement) e);
}
}
public void close()
{
write();
layoutDocument.flush();
layoutDocument.close();
}
}
You can then easily call this facade to do the work for you.
File outputFile = new File(System.getProperty("user.home"), "output.pdf");
ITextForDummiesFacade facade = new ITextForDummiesFacade(outputFile);
facade.createChapter("Chapter 1");
facade.addPlainText("Chapter 1","Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.");
facade.close();
I have the following code to display the spectrum of audio.But it uses URI.But how to use simple paths like C:/abc/asas.wav ...or something?Any idea?
It gives me Exception when i use local paths:
Exception in thread "main" java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(Unknown Source)
at com.sun.javafx.application.LauncherImpl.access$000(Unknown Source)
at com.sun.javafx.application.LauncherImpl$1.run(Unknown Source)
at java.lang.Thread.run(Thread.java:722)
Code:
package chartaudiobar;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.media.AudioSpectrumListener;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.stage.Stage;
public class ChartAudioBar extends Application {
private XYChart.Data<String, Number>[] series1Data;
private AudioSpectrumListener audioSpectrumListener;
private static final String AUDIO_URI = System.getProperty("demo.audio.url","http://download.oracle.com/otndocs/products/javafx/oow2010-2.flv");
private static MediaPlayer audioMediaPlayer;
private static final boolean PLAY_AUDIO = Boolean.parseBoolean(System.getProperty("demo.play.audio","true"));
private void init(Stage primaryStage) {
Group root = new Group();
primaryStage.setScene(new Scene(root));
root.getChildren().add(createChart());
audioSpectrumListener = new AudioSpectrumListener() {
#Override public void spectrumDataUpdate(double timestamp, double duration,
float[] magnitudes, float[] phases) {
for (int i = 0; i < series1Data.length; i++) {
series1Data[i].setYValue(magnitudes[i] + 60);
}
}
};
}
public void play() {
this.startAudio();
}
#Override public void stop() {
this.stopAudio();
}
protected BarChart<String, Number> createChart() {
final CategoryAxis xAxis = new CategoryAxis();
final NumberAxis yAxis = new NumberAxis(0,50,10);
final BarChart<String,Number> bc = new BarChart<String,Number>(xAxis,yAxis);
bc.setId("barAudioDemo");
bc.setLegendVisible(false);
bc.setAnimated(false);
bc.setBarGap(0);
bc.setCategoryGap(1);
bc.setVerticalGridLinesVisible(false);
// setup chart
bc.setTitle("Live Audio Spectrum Data");
xAxis.setLabel("Frequency Bands");
yAxis.setLabel("Magnitudes");
yAxis.setTickLabelFormatter(new NumberAxis.DefaultFormatter(yAxis,null,"dB"));
// add starting data
XYChart.Series<String,Number> series1 = new XYChart.Series<String,Number>();
series1.setName("Data Series 1");
//noinspection unchecked
series1Data = new XYChart.Data[128];
String[] categories = new String[128];
for (int i=0; i<series1Data.length; i++) {
categories[i] = Integer.toString(i+1);
series1Data[i] = new XYChart.Data<String,Number>(categories[i],50);
series1.getData().add(series1Data[i]);
}
bc.getData().add(series1);
return bc;
}
private void startAudio() {
if (PLAY_AUDIO) {
getAudioMediaPlayer().setAudioSpectrumListener(audioSpectrumListener);
getAudioMediaPlayer().play();
}
}
private void stopAudio() {
if (getAudioMediaPlayer().getAudioSpectrumListener() == audioSpectrumListener) {
getAudioMediaPlayer().pause();
}
}
private static MediaPlayer getAudioMediaPlayer() {
if (audioMediaPlayer == null) {
Media audioMedia = new Media(AUDIO_URI);
audioMediaPlayer = new MediaPlayer(audioMedia);
}
return audioMediaPlayer;
}
#Override public void start(Stage primaryStage) throws Exception {
init(primaryStage);
primaryStage.show();
play();
}
public static void main(String[] args) { launch(args); }
}
So how to use local paths here?
I had the same problem, i used this:
File file = new File("C:\\abc\\asas.wav");
audio = new Media(file.toURI().toURL().toString());
audioMediaPlayer = new MediaPlayer(audio);
You can convert path to URI by adding protocol
C:/abc/asas.wav will be file:/C:/abc/asas.wav in Your example
It’s 4 years after Jyoti Shaw posted this question, how to use a local music file in class ChartAudioBar. Wafu has the answer on his webpage https://osu.ppy.sh/forum/p/4629060 Look about halfway down on the page, under his heading “Frequency spectrum” and click on “Code” to see the source code.
Wafu’s solution is similar to that of Sam de Meyer in his answer above.
//We don't need this line, because we need to use a local music file.
//private static final String AUDIO_URI = System.getProperty("demo.audio.url","http://download.oracle.com/otndocs/products/javafx/oow2010-2.flv");
private static MediaPlayer audioMediaPlayer;
//We don't need this as well as it's equally useless as previous thing.
//private static final boolean PLAY_AUDIO = Boolean.parseBoolean(System.getProperty("demo.play.audio","true"));
//We anyway need output of the default chart, so let's say we'll put it to file data.txt, hence the 'import java.io.File' needs to be added to imports.
private static File filedata = new File("data.txt");
// *****************************************************************************
private static MediaPlayer getAudioMediaPlayer() {
if (audioMediaPlayer == null) {
//We need code below, but I commented it anyway to show the difference, we need a local file, so this won't work.
//Media audioMedia = new Media(AUDIO_URI);
//So we create a local file, for example mp3.mp3 in current folder, it can be anything you want.
//File audiofile = new File("mp3.mp3");
File audiofile = new File("C:/music/SummerMix.mp3");
//Now we need to make audioMedia as it was previously - So it needs to be URI, which .toURI() ensures easily, but as well as that, it needs a string URI, so .toString() will ensure this.
Media audioMedia = new Media(audiofile.toURI().toString());
audioMediaPlayer = new MediaPlayer(audioMedia);
}
return audioMediaPlayer;
}
I am creating a PDF reader in java. For reading PDF files i am using iText library. I have a sample code to read the PDF files but i don't know how to display the iText Image object in a JFrame.Below is the code to read a PDF file.
import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfWriter;
public class ReadAndUsePdf {
private static String INPUTFILE = "c:/temp/FirstPdf.pdf";
private static String OUTPUTFILE = "c:/temp/ReadPdf.pdf";
public static void main(String[] args) throws DocumentException,
IOException {
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document,
new FileOutputStream(OUTPUTFILE));
document.open();
PdfReader reader = new PdfReader(INPUTFILE);
int n = reader.getNumberOfPages();
PdfImportedPage page;
// Go through all pages
for (int i = 1; i <= n; i++) {
// Only page number 2 will be included
if (i == 2) {
page = writer.getImportedPage(reader, i);
Image instance = Image.getInstance(page); //how to show this object in a JFrame
document.add(instance);
}
}
document.close();
}
}
I have the exactly same problem, and I solved it by using ICEPdf to render the PDF in Swing, and iText to manipulate it.
Possible duplication: Can I use iText to render PDF in my Swing application?