title: How to generate a downloadable PDF with pdfbox (Corrupted PDF)?
body: <p>How do I make a PDF file downloadable in a link?</p>
  
  <p>I'm building a web application using JSF, when the user clicks in a "Save as PDF" link a PDF should be available to be downloaded.</p>
  
  <p>So far I've a working code that generates the PDF file, but the file is saved on my desktop and what I want to do is that when the user clicks on the link the pdf file should be downloadable instead of being stored in the app.</p>
  
  <p><strong>UPDATE 3:</strong>
  <em>Thank you for your help guys, I modifed my code with your suggestions and it's working.</em></p>
  
  <p><strong>UPDATE 2:</strong>
  <em>I'm getting the following error: Adoble Reader could not open "yourfile.pdf" because is either not a supported file type or because the file has been damaged</em></p>
  
  <p><strong>UPDATE 1:</strong>
  <em>I'm adding my current code with the changes you have pointed me out, however I'm still struggling to make this work</em></p>
  
  <blockquote>
    <p><strong>This is my method that generated the PDF:</strong></p>
  </blockquote>
  
  <pre><code>public ByteArrayOutputStream createPDF() throws IOException, COSVisitorException {
  
      PDDocument document;
      PDPage page;
      PDFont font;
      PDPageContentStream contentStream;
      PDJpeg front;
      PDJpeg back;
  
      InputStream inputFront;
      InputStream inputBack;
      ByteArrayOutputStream output = new ByteArrayOutputStream(); 
  
      // Creating Document
      document = new PDDocument();
  
      // Creating Pages
      for(int i=0; i&lt;2; i++) {
  
          page = new PDPage();
  
          // Adding page to document
          document.addPage(page); 
  
          // Adding FONT to document
          font = PDType1Font.HELVETICA;           
  
          // Retrieve Image to be added to the PDF
          inputFront = new FileInputStream(new File("D:/Media/imageFront.jpg"));  
          inputBack = new FileInputStream(new File("D:/Media/imageBack.jpg"));
  
          BufferedImage buffFront = ImageIO.read(inputFront);
          BufferedImage resizedFront = Scalr.resize(buffFront, 460);
  
          BufferedImage buffBack = ImageIO.read(inputBack);
          BufferedImage resizedBack = Scalr.resize(buffBack, 460); 
  
          front = new PDJpeg(document, resizedFront);
          back = new PDJpeg(document, resizedBack);
  
          // Next we start a new content stream which will "hold" the to be created content.
          contentStream = new PDPageContentStream(document, page);                
  
          // Let's define the content stream
          contentStream.beginText();
          contentStream.setFont(font, 8);
          contentStream.moveTextPositionByAmount(10, 770);
          contentStream.drawString("Amount: $1.00");
          contentStream.endText();
  
          contentStream.beginText();
          contentStream.setFont(font, 8);
          contentStream.moveTextPositionByAmount(200, 770);
          contentStream.drawString("Sequence Number: 123456789");
          contentStream.endText();
  
          contentStream.beginText();
          contentStream.setFont(font, 8);
          contentStream.moveTextPositionByAmount(10, 760);
          contentStream.drawString("Account: 123456789");
          contentStream.endText();
  
          contentStream.beginText();
          contentStream.setFont(font, 8);
          contentStream.moveTextPositionByAmount(200, 760);
          contentStream.drawString("Captura Date: 04/25/2011");
          contentStream.endText();
  
          contentStream.beginText();
          contentStream.setFont(font, 8);
          contentStream.moveTextPositionByAmount(10, 750);
          contentStream.drawString("Bank Number: 123456789");
          contentStream.endText();
  
          contentStream.beginText();
          contentStream.setFont(font, 8);
          contentStream.moveTextPositionByAmount(200, 750);
          contentStream.drawString("Check Number: 123456789");
          contentStream.endText();            
  
          // Let's close the content stream       
          contentStream.close();
  
      }
  
      // Finally Let's save the PDF
      document.save(output);
      document.close();
  
      return output;
  }
  </code></pre>
  
  <blockquote>
    <p><strong>This is my servlet that call the previous code and generates the output and set the header:</strong></p>
  </blockquote>
  
  <pre><code>try {
  
          ByteArrayOutputStream output = new ByteArrayOutputStream();
          output = createPDF();
  
          response.addHeader("Content-Type", "application/force-download"); 
          response.addHeader("Content-Disposition", "attachment; filename=\"yourFile.pdf\"");
          response.getOutputStream().write(output.toByteArray());
  
      } catch (Exception ex) {            
          ex.printStackTrace();
      }   
  </code></pre>
  
  <p>I'm not sure what I'm missing since when I try to open the PDF I got the error: Adoble Reader could not open "yourfile.pdf" because is either not a supported file type or because the file has been damaged</p>