How to merge List<PdfDocument> into a single PdfDocument - java

I have a List with multiple PDFs , and I want to merge all of them into a single PdfDocument (im using iText) , and then transform this PdfDocument into a ByteArrayOutputStream (OR a byte[]).
public byte[] mergePdfDocumentsIntoAPdfDocument (List<PdfDocument> pdfDocuments){
final ByteArrayOutputStream mergedPdfStream = new ByteArrayOutputStream();
final PdfDocument mergedPdfDocument = new PdfDocument(new PdfWriter(mergedPdfStream));
//I dont know how can I continue this
What should I do in order to achieve this?

public byte[] mergePdfDocumentsIntoAPdfDocument(List<PdfDocument> pdfDocuments){
ByteArrayOutputStream mergedPdfStream = new ByteArrayOutputStream();
PdfDocument resultDoc = new PdfDocument(new PdfWriter(mergedPdfStream));
for (PdfDocument doc : pdfDocuments) {
int n = doc.getNumberOfPages();
for (int i = 1; i <= n; i++) {
PdfPage page = doc.getPage(i).copyTo(resultDoc);
resultDoc.addPage(page);
}
}
resultDoc.close();
return mergedPdfStream.toByteArray();
}

Related

PDF File generated by PdfWriter is showing blank page

I have code to merge between 2 pdf files using the library OpenPDF like this
public byte[] mergePDF(byte[] pdf1, byte[] pdf2) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
Document document = new Document();
PdfWriter writer;
try {
writer = PdfWriter.getInstance(document, os);
} catch (DocumentException e) {
throw new IllegalStateException(e);
}
document.open();
PdfContentByte cb = writer.getDirectContent();
PdfReader pdfReader1 = new PdfReader(pdf1);
PdfReader pdfReader2 = new PdfReader(pdf2);
for (int i = 0; i < pdfReader1.getNumberOfPages(); i++) {
PdfImportedPage page = writer.getImportedPage(pdfReader1, i + 1);
document.setPageSize(pdfReader1.getPageSize(i + 1));
document.newPage();
cb.addTemplate(page, 0, 0);
}
for (int i = 0; i < pdfReader2.getNumberOfPages(); i++) {
PdfImportedPage page = writer.getImportedPage(pdfReader2, i + 1);
document.setPageSize(pdfReader2.getPageSize(i + 1));
document.newPage();
cb.addTemplate(page, 0, 0);
}
document.close();
return os.toByteArray();
}
Merged PDF generated showing a blank page from on Page come from the second pdf but it showing when open with adobe acrobat, firefox, and ubuntu document viewer. Does anyone know what issue? or any missing configuration that needs to be set in my code?

downloading blank pdf pages with itext and ACJRuntime.jar

I have an xml file and .doj template file. trying to download a PDF using itext.jar and ACTRuntime.jar. It is working in java 1.6 and Websphere 7 but after migrating to java 8 and websphere 8, it is just downloading blank white pages in PDF format.
Below is the code that I'm using to produce PDF.
public ByteArrayOutputStream generatePdf(){
ArrayList<Object> bean = new ArrayList<Object>();
BeanOne beanOne = new BeanOne();
beanOne.setId(1);
beanOne.setName("Sai");
beanOne.setPhone("1234567890");
BeanOne beanOne1 = new BeanOne();
beanOne1.setId(2);
beanOne1.setName("Ram");
beanOne1.setPhone("9876543210");
bean.add(beanOne);
bean.add(beanOne1);
AppDataHandler ds = new AppDataHandler();
String tableName = "First Talbe";
Object obj= bean.get(0);
Vector fields = new Vector();
fields.addElement("id = getId");
fields.addElement("name = getName");
fields.addElement("phone = getPhone");
ds.registerObjectAsTable(obj, tableName, fields);
ds.registerDataSet(tableName, bean);
FileInputStream reportTemplateInputStream = new FileInputStream(new File("/template.jod"));
ACJEngine acjEngine = new ACJEngine();
acjEngine.readTemplate(reportTemplateInputStream);
TemplateManager templateManager = acjEngine.getTemplateManager();
templateManager.setLabel("ID", "ID");
templateManager.setLabel("NAME", "NAME");
templateManager.setLabel("PHONE", "PHONE");
acjEngine.setX11GfxAvailibility(false);
acjEngine.setDataSource(ds);
ACJOutputProcessor ec = new ACJOutputProcessor();
IViewerInterface ivi = acjEngine.generateReport();
ByteArrayOutputStream generatedPDFStream = new ByteArrayOutputStream();
ec.setPDFProperty("OutputStream", generatedPDFStream);
ec.generatePDF();
reportTemplateInputStream.close();
Object[] pdfFromActuateArray = new Object[1];
pdfFromActuateArray[0] = generatedPDFStream.toByteArray();
return mergePdfsUsingItext(pdfFromActuateArray);
}
private ByteArrayOutputStream mergePdfsUsingItext(Object[] documents) throws com.itextpdf.text.DocumentException {
ByteArrayOutputStream content = new ByteArrayOutputStream();
int f;
byte[] byteDoc = null;
for (f = 0; f < documents.length; ++f) {
byteDoc = (byte[]) documents[f];
if (byteDoc != null)
break;
}
PdfReader reader = new PdfReader(byteDoc);
int n = reader.getNumberOfPages();
Document document = new Document(reader.getPageSizeWithRotation(1));
PdfWriter writer = PdfWriter.getInstance(document, content);
document.open();
PdfContentByte cb = writer.getDirectContent();
PdfImportedPage page;
int rotation;
while (f < documents.length) {
int i = 0;
while (i < n) {
i++;
document.setPageSize(reader.getPageSizeWithRotation(i));
document.newPage();
page = writer.getImportedPage(reader, i);
cb.addTemplate(page, 1f, 0, 0, 1f, 0, 0);
}
f++;
if (f < documents.length) {
reader = new PdfReader((byte[]) documents[f]);
n = reader.getNumberOfPages();
}
}
document.close();
return content;
}
With the above code I'm getting the ByteArrayOutputStream which I'm printing on the jsp page with content-type as application/pdf.
The result pdf is completely blank. Hope Someone could explain the issue. Also please suggest any good alternative to this code.
Thanks in Advance.

How to read data from excel using apache poi and store the data into String[][] array?

I want to read data from excel using apache poi and store that data into 2Dimentional String Array. Using below code I will display data but I want to store the data.
public static void main(String[] args) throws Exception {
File f = new File("C:/Users/SYKAMREDDY/Desktop/testData.xls");
FileInputStream fis = new FileInputStream(f);
HSSFWorkbook wb = new HSSFWorkbook(fis);
HSSFSheet sh = wb.getSheet("Data");
int rc=sh.getLastRowNum()-sh.getFirstRowNum();
for (int i = 1; i < rc; i++) {
Row r = sh.getRow(i);
for (int j = 1; j < r.getLastCellNum(); j++) {
String s = r.getCell(j).getStringCellValue();
System.out.print(s+" ");
}
System.out.println();
}
}
Try to use byteArray
simplified example:
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
workbook.write(bos);
} finally {
bos.close();
}
byte[] bytes = bos.toByteArray();
also, take a look at How can I convert POI HSSFWorkbook to bytes?
if you want to use string , simpy do
String s = new String(bytes);

How to Check pdf file contain scanned page or not using itext library in java

I am using itext library to merge multiple pdfs, I am able to merge multiple pdfs but if pdf contain scan pages then i don't want to add it in merged PDF, Does it possible to check scan pages using itext?.
I am using Following code to merge pdf.
Document PDFJoinInJava = new Document();
PdfCopy PDFCombiner = new PdfCopy(PDFJoinInJava, outputStream);
PdfCopy.PageStamp stamp;
PDFJoinInJava.open();
PdfReader ReadInputPDF;
List<InputStream> pdfs = streamOfPDFFiles;
List<PdfReader> readers = new ArrayList<PdfReader>();
int totalPages = 0;
Iterator<InputStream> iteratorPDFs = pdfs.iterator();
for (; iteratorPDFs.hasNext(); pdfCounter++) {
InputStream pdf = iteratorPDFs.next();
PdfReader pdfReader = new PdfReader(pdf);
readers.add(pdfReader);
totalPages += pdfReader.getNumberOfPages();
pdf.close();
}
int number_of_pages;
int currentPageNumber = 0;
int pageOfCurrentReaderPDF = 0;
Iterator<PdfReader> iteratorPDFReader = readers.iterator();
PdfImportedPage page;
// Loop through the PDF files and add to the output.
int count = 1;
while (iteratorPDFReader.hasNext()) {
PdfReader pdfReader = iteratorPDFReader.next();
count++;
number_of_pages = pdfReader.getNumberOfPages();
// Create a new page in the target for each source page.
for (int pageNum = 0; pageNum < number_of_pages;) {
currentPageNumber++;
pageOfCurrentReaderPDF++;
page = PDFCombiner.getImportedPage(pdfReader, ++pageNum);
ColumnText.showTextAligned(stamp.getUnderContent(),
Element.ALIGN_RIGHT, new Phrase(String
.format("%d", currentPageNumber),new Font(FontFamily.TIMES_ROMAN,3)),
50, 50, 0);
stamp.alterContents();
PDFCombiner.addPage(page);
}
}
PDFJoinInJava.close();
If you like to find whether pdf file is generated by iText or not then you have to try following code:
File file = new File("/Demo.pdf");
Scanner input = new Scanner(new FileReader(file));
while (input.hasNextLine()) {
final String checkline = input.nextLine();
if(checkline.contains("Producer(iText")) {
// a match found!!!!!!
System.out.println(file.getName()+" is generated by iText........ :):) ");
break;
}
}

How to add a page number to the output pdf when merging two pdfs?

I am using the following code to merge two pdfs:
File firstPdfFile = new File("firstPdf.pdf");
File secondPdfFile = new File("secondPdf.pdf");
PDFMergerUtility merger = new PDFMergerUtility();
merger.addSource(firstPdfFile);
merger.addSource(secondPdfFile);
String pdfPath = "PdfFile.pdf";
OutputStream bout2 = new BufferedOutputStream(new FileOutputStream(pdfPath));
merger.setDestinationStream(bout2);
merger.mergeDocuments();
File pdfFile = new File(pdfPath);
I am getting the merged pdf correctly but I want to add page number in this pdf file.
Try this code.
File firstPdfFile = new File("firstPdf.pdf");
File secondPdfFile = new File("firstPdf.pdf");
PDFMergerUtility merger = new PDFMergerUtility();
merger.addSource(firstPdfFile);
merger.addSource(secondPdfFile);
String pdfPath = "PdfFile.pdf";
OutputStream bout2 = new BufferedOutputStream(new FileOutputStream(pdfPath));
merger.setDestinationStream(bout2);
merger.mergeDocuments();
PDDocument doc = null;
try {
URL file = new URL("file:///PdfFile.pdf");
doc = PDDocument.load(file);
List<?> allPages = doc.getDocumentCatalog().getAllPages();
PDFont font = PDType1Font.HELVETICA_BOLD;
float fontSize = 36.0f;
for (int i = 0; i < allPages.size(); i++) {
PDPage page = (PDPage) allPages.get(i);
PDPageContentStream footercontentStream = new PDPageContentStream(doc, page, true, true);
footercontentStream.beginText();
footercontentStream.setFont(font, fontSize);
footercontentStream.moveTextPositionByAmount((PDPage.PAGE_SIZE_A4.getUpperRightX() / 2), (PDPage.PAGE_SIZE_A4.getLowerLeftY()));
footercontentStream.drawString(String.valueOf(i + 1));
footercontentStream.endText();
footercontentStream.close();
}
doc.save("PdfFile.pdf");
} finally {
if (doc != null) {
doc.close();
}
}
Try below code for PDFBox 2.0
public class PageNumberExample {
final boolean isCompress = false;
final boolean isContextReset = true;
public static void main(String[] args) throws IOException {
new PageNumberExample().addPageNumber("merged PDF path");
}
public void addPageNumber(String pdfPath) throws IOException {
File mergePpdfFile = new File(pdfPath);
PDDocument document = PDDocument.load(mergePpdfFile);
int totalPage = document.getNumberOfPages();
for(int i=0; i<totalPage; i++) {
PDPage page = document.getPage(i);
PDPageContentStream stream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, isCompress, isContextReset);
stream.setNonStrokingColor(Color.BLACK);
stream.beginText();
stream.setFont(PDType1Font.COURIER, 10);
stream.newLineAtOffset(100, 100); //Set position where you want to print page number.
stream.showText("Page " + (i+1) + " of " + totalPage);
stream.endText();
stream.close();
}
document.save(pdfPath);
document.close();
}
}

Categories