How to merge two PDF files into one in Java?
Why not use the PDFMergerUtility of pdfbox?
PDFMergerUtility ut = new PDFMergerUtility();
ut.addSource(...);
ut.addSource(...);
ut.addSource(...);
ut.setDestinationFileName(...);
ut.mergeDocuments();
Merge pdf files within folder java
Here is a working example. I have used ITEXT
Dependencies :
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.10</version>
</dependency>
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfSmartCopy;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.List;
/**
* Created by RGOVIND on 11/7/2016.
*/
public class MergePDF {
static public void main(String[] args) throws Exception{
mergePDF("C:\\XX\\PDF","mergedFile.pdf");
}
public static void mergePDF(String directory, String targetFile) throws DocumentException, IOException {
File dir = new File(directory);
File[] filesToMerge = dir.listFiles(new FilenameFilter() {
public boolean accept(File file, String fileName) {
//System.out.println(fileName);
return fileName.endsWith(".pdf");
}
});
Document document = new Document();
FileOutputStream outputStream = new FileOutputStream("C:\\DevelopmentTools\\PDF\\"+targetFile);
PdfCopy copy = new PdfSmartCopy(document, outputStream);
document.open();
for (File inFile : filesToMerge) {
System.out.println(inFile.getCanonicalPath());
PdfReader reader = new PdfReader(inFile.getCanonicalPath());
copy.addDocument(reader);
reader.close();
}
document.close();
}
}
merge many pdf files into one pdf files in web application java
There are numerous errors in your code:
Only write to the response output stream what you want to return to the browser
Your code writes a wild collection of data to the response output stream:
ServletOutputStream servletOutPutStream = response.getOutputStream();;
[...]
for(byte[] imageList:imageMap)
{
[...]
byteArrayOutputStream.writeTo(response.getOutputStream());
[...]
}
[...]
PdfWriter writer = PdfWriter.getInstance(document, response.getOutputStream());
[... merge PDFs into the writer]
servletOutPutStream.flush();
document.close();
servletOutPutStream.close();
This results in many copies of the imageMap
elements to be written there and the merged file only to be added thereafter.
What do you expect the browser to do, ignore all the leading source PDF copies until finally the merged PDF appears?
Thus, please only write the merged PDF to the response output stream.
Don't write a wrong content length
It is a good idea to write the content length to the response... but only if you use the correct value!
In your code you write a content length:
response.setContentLength(byteArrayOutputStream.size());
but the byteArrayOutputStream
at this time only contains a wild mix of copies of the source PDFs and not yet the final merged PDF. Thus, this will only serve to confuse the browser even more.
Thus, please do not add false headers to the response.
Don't mangle your input data
In the loop
for(byte[] imageList:imageMap)
{
System.out.println(imageList.toString()+" "+imageList.length);
byteArrayOutputStream.write(imageList);
byteArrayOutputStream.writeTo(response.getOutputStream());
is = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
inputPdfList.add(is);
}
you take byte
arrays which I assume contain a single source PDF each, pollute the response output stream with them (as mentioned before), and create a collection of input streams where the first one contains the first source PDF, the second one contains the concatenation of the first two source PDFs, the third one the concatenation of the first three source PDFs, etc...
Because you never reset or re-instantiate the byteArrayOutputStream
, it only gets bigger and bigger.
Thus, please start or end loops like this with a reset of the byteArrayOutputStream
.
(Actually you don't need that loop at all, the PdfReader
has a constructor which can immediately take a byte[]
, no need to wrap it in a byte stream.)
Don't merge PDFs using a plain PdfWriter
, use a PdfCopy
You merge the PDFs using a PdfWriter
/ getImportedPage
/ addTemplate
approach. There are dozens of questions and answer on stack overflow (many of them answered by iText developers) explaining that this usually is a bad idea and that you should use PdfCopy
.
Thus, please make use of the many good answers which already exist on this topic here and use PdfCopy
for merging.
Don't flush or close streams only because you can
You finalize the response output by closing numerous streams:
//Close document and outputStream.
servletOutPutStream.flush();
outputStream.flush();
document.close();
outputStream.close();
servletOutPutStream.close();
I have not seen a line in which you declared or set that outputStream
variable, but even if it contained the response output stream, there is no need to close that because you already close it in the servletOutPutStream
variable.
Thus, please remove unnecessary calls like this.
Java - How to merge multiple documents (With Multiple file formats with file convert) to a single PDF?
Answering to My Own question to Benefit another person.
In order to Convert Files with extensions docx , xlsx , pptx) Used
Spire.Office for Java (Free Evaluation version available)
Also I tried aspose cells libray as well (Free Evaluation available) to convert xlsx to PDF as well. Both Libraries worked fine and hassle free , But all libraries were not free.
Then Merged all the PDF Files using ITEXT Library.
If Someone is having a better alternative answer , kindly share.
For multiple files merge, you can refer This Example
How merge and rotate two pdf pages to one page itext
Merge:
public void mergeTwoPagesIntoOne(String originalPdfFile, String outputPdfFile) throws IOException, DocumentException {
PdfReader reader = new PdfReader(originalPdfFile);
Document doc = new Document(new RectangleReadOnly(842f, 595f), 0, 0, 0, 0);
PdfWriter writer = PdfWriter.getInstance(doc, new FileOutputStream(outputPdfFile));
doc.open();
int totalPages = reader.getNumberOfPages();
for (int i = 1; i <= totalPages; i = i + 2) {
doc.newPage();
PdfContentByte cb = writer.getDirectContent();
PdfImportedPage page = writer.getImportedPage(reader, i); // page #1
float documentWidth = doc.getPageSize().getWidth() / 2;
float documentHeight = doc.getPageSize().getHeight();
if (i > 1)
documentHeight = documentHeight - 50f;
float pageWidth = page.getWidth();
float pageHeight = page.getHeight();
float widthScale = documentWidth / pageWidth;
float heightScale = documentHeight / pageHeight;
float scale = Math.min(widthScale, heightScale);
float offsetX = (documentWidth - (pageWidth * scale)) / 2;
float offsetY = 0f;
cb.addTemplate(page, scale, 0, 0, scale, offsetX, offsetY);
if (i+1 <= totalPages) {
PdfImportedPage page2 = writer.getImportedPage(reader, i+1); // page #2
pageWidth = page.getWidth();
pageHeight = page.getHeight();
widthScale = documentWidth / pageWidth;
heightScale = documentHeight / pageHeight;
scale = Math.min(widthScale, heightScale);
offsetX = ((documentWidth - (pageWidth * scale)) / 2) + documentWidth;
cb.addTemplate(page2, scale, 0, 0, scale, offsetX, offsetY);
}
}
doc.close();
}
Rotate:
public void rotatePdf(String originalPdfFile, String outputPdfFile, int degrees) throws IOException, DocumentException {
PdfReader reader = new PdfReader(originalPdfFile);
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
PdfDictionary dictionary = reader.getPageN(i);
dictionary.put(PdfName.ROTATE, new PdfNumber(degrees));
}
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputPdfFile));
stamper.close();
reader.close();
}
Related Topics
Converting an Array of Objects to an Array of Their Primitive Types
Why Shouldn't You Extend Jframe and Other Components
Building Executable Jar with Maven
How to Find the Sum of All the Numbers in an Array in Java
How to Add Unicode in Truetype0Font on PDFbox 2.0.0
Why Does Javac Complain About Generics Unrelated to the Class' Type Arguments
Why Is Java's Iterator Not an Iterable
Jersey Stopped Working with Injectionmanagerfactory Not Found
Java Protected Fields VS Public Getters
Platform Independent Paths in Java
Garbage Collector in Java - Set an Object Null
Difference in System. Exit(0) , System.Exit(-1), System.Exit(1 ) in Java
How to Read JSON File into Java with Simple JSON Library
Efficient Swapping of Elements of an Array in Java