0

In my current code I am merging the documents consisting PDF files.

public static void appApplicantDownload(File file) {

 Connection con = getConnection();
 Scanner sc = new Scanner(System.in);
 List < InputStream > list = new ArrayList < InputStream > ();
 try {
  OutputStream fOriginal = new FileOutputStream(file, true); // original

  list.add(new FileInputStream(file1));
  list.add(new FileInputStream(file2));
  list.add(new FileInputStream(file3));
  doMerge(list, fOriginal);

 } catch (Exception e) {

 }
}




public static void doMerge(List < InputStream > list, OutputStream outputStream) throws DocumentException, IOException {
 try {
  System.out.println("Merging...");
  Document document = new Document();
  PdfCopy copy = new PdfCopy(document, outputStream);
  document.open();

  for (InputStream in : list) {
   ByteArrayOutputStream b = new ByteArrayOutputStream();
   IOUtils.copy( in , b);
   PdfReader reader = new PdfReader(b.toByteArray());

   for (int i = 1; i <= reader.getNumberOfPages(); i++) {
    copy.addPage(copy.getImportedPage(reader, i));
   }
  }

  outputStream.flush();
  document.close();
  outputStream.close();
 } catch (Exception e) {
  e.printStackTrace();
 }
}

But now I want to change the code such that it should allow Image as well as PDFs to be merged. Above code is giving me the error that No PDF Signature found

Govinda Sakhare
  • 5,009
  • 6
  • 33
  • 74
  • 1
    if the code's supposed to merge PDF, would you expect to be able to throw a spreadsheet in the mix and have it work ? Welp it's the same with an image, the PDF handling library is complaining that what you've fed it isn't a PDF. – Aaron May 17 '17 at 16:39
  • Yes I know, there is nothing wrong with the library, it is expecting PDF signature. I can convert image to Image to PDF and then merge. I want to know the elegant way to do it. – Govinda Sakhare May 17 '17 at 16:43

2 Answers2

2

First, you have to know somehow if the file is a PDF or an image. The easiest way would be to use the extension of the file. So you would have get extension of the file and then pass this information to your doMerge method. Do achieve that, I would change your current method

public static void doMerge(List<InputStream> list, OutputStream outputStream)

For something like

public static void doMerge(Map<InputStream, String> files, OutputStream outputStream)

So each InputStream is associated with a extension.

Second, you have to load images and pdf seperately. So your loop should look like

for (InputStream in : files.keySet()) {
    String ext = files.get(in);

    if(ext.equalsIgnoreCase("pdf"))
    {
        //load pdf here
    }
    else if(ext.equalsIgnoreCase("png") || ext.equalsIgnoreCase("jpg"))
    {
        //load image here
    }
}

In java, you can easily load an Image using ImageIO. Look at this question for more details on this topic: Load image from a filepath via BufferedImage

Then to add your image into the PDF, use the PdfWriter

PdfWriter pw = PdfWriter.GetInstance(doc, outputStream);
Image img = Image.GetInstance(inputStream);
doc.Add(img);
doc.NewPage();

If you want to convert your image into PDF before and merge after you also can do that but you just have to use the PdfWriter to write them all first.

Community
  • 1
  • 1
Winter
  • 3,894
  • 7
  • 24
  • 56
  • Seems like we are not on same page. I can find which one is image and which one is PDF. What I want to know how can I convert Image to PDF and then PDF back to InputStream. – Govinda Sakhare May 17 '17 at 16:46
  • I would use the strategy pattern instead (https://dzone.com/articles/design-patterns-strategy) but yeah, in general the same idea. – Amedee Van Gasse May 17 '17 at 16:49
  • You cannot **convert** image into PDF, you can **place** image into PDF's page. Its not like converting JPG to GIF. – Todor Simeonov May 17 '17 at 16:49
  • @piechuckerr Added the part of the answer you were looking for. – Winter May 17 '17 at 16:51
0

Create a new page in the opened PDF document and use the function for inserting images to place the image on that page.

Todor Simeonov
  • 806
  • 1
  • 6
  • 11