-1

I do create PDF from String which this String is in xml format and present to user as a trinidad button with fileDownloadActionListener.

I can download the PDF but can't open it with PDF reader such as adobe reader first I thought it maybe corrupted but it is not the case because I can open it with Visual Studio Code or any other text editor such as notepad.

1- why I can't open it with adobe reader?

2- Is there any better why to do this?

Frontend:

<h:commandButton id="mehrpdf" value="Download PDF" styleClass="popupButton">
        <tr:fileDownloadActionListener filename="mehr.pdf"  contentType="application/pdf; charset=utf-8" method="#{bean.downloadMehr}" />
</h:commandButton>

Backend:

public void downloadMehr(FacesContext context, OutputStream out) throws IOException
    {
        String fetchedXmlMessage = getFetchedXmlMessage();
        XmlPrettifier prettifier = XmlPrettifierFactory.getInstance();
        prettyXmlMessage = prettifier.makePretty(fetchedXmlMessage);

        // alternativ way
        File pdfFile = createPdfFromTxt(prettyXmlMessage);

        OutputStreamWriter w = new OutputStreamWriter(out, "UTF-8");
        w.write(prettyXmlMessage);
        w.flush();
    }

pdfcreation:

public File createPdfFromTxt(String content) throws IOException, DocumentException {

        //define the size of the PDF file, version and output file
        File outfile = File.createTempFile("mehr", ".pdf");
        Document pdfDoc = new Document(PageSize.A4);
        PdfWriter.getInstance(pdfDoc, new FileOutputStream(outfile)).setPdfVersion(PdfWriter.PDF_VERSION_1_7);
        pdfDoc.open();

        //define the font and also the command that is used to generate new paragraph
        Font myfont = new Font();
        myfont.setStyle(Font.NORMAL);
        myfont.setSize(11);
        pdfDoc.add(new Paragraph("\n"));

        // add paragraphs into newly created PDF file
        File contentFile = File.createTempFile("content", ".txt");
        FileUtils.writeStringToFile(contentFile, content);

        BufferedReader br = new BufferedReader(new FileReader(contentFile));
        String strLine;
        while ((strLine = br.readLine()) != null) {
            Paragraph para = new Paragraph(strLine + "\n", myfont);
            para.setAlignment(Element.ALIGN_JUSTIFIED);
            pdfDoc.add(para);
        }
        pdfDoc.close();
        br.close();

        return outfile;
    }
itro
  • 7,006
  • 27
  • 78
  • 121
  • 2
    What do you mean with "I can open it with Visual Studio Code."? Do you use an PDF-Preview addon in VS Code? My suggestion would be to open the PDF with a text editor to see if there is some text (probably some log- or error-message) before the PDF-Header (`%pdf-...`?). – Ocaso Protal Jun 17 '20 at 06:26
  • 2
    Because you used a `Writer` instead of an `OutputStream`. `Writer` is for character data. PDFs are binary. Why you're treating a PDF as XML is another mystery. – user207421 Jun 17 '20 at 06:46
  • @OcasoProtal I can open it with other text editor such as notepad too. There is also nothing before header. `` is the first line. – itro Jun 17 '20 at 07:07
  • @MarquisofLorne we don't treat PDF as XML we try to treat xml as text and display it on pdf. The reason is simple, we want to see the tags too. About writer, this is want I found on api therefore I used as is. In your opinion what should I change in the code? – itro Jun 17 '20 at 07:17
  • 3
    Well, than you are not creating an PDF! Please post your `createPdfFromTxt` Method – Ocaso Protal Jun 17 '20 at 07:20
  • 4
    Not a word of this makes any sense. You are allegedly receiving XML, converting that to PDF, throwing away the resulting `File`, saving the XML with a `Writer`, and then trying to open it with (i) a PDF reader, (ii) VIsual Studio, and (iii) a text editor. You need to copy from the `File` to the output, using input and output streams only, and probably delete the file afterwards. – user207421 Jun 17 '20 at 07:26
  • @OcasoProtal I did update as you requested. I think there is no problem with the creation of PDF, I see it in the local temp directory and I can open it. – itro Jun 17 '20 at 07:43
  • @MarquisofLorne we don't throwing away the pdfFile As you can see I have commented the created pdfFile as alternative way, honestly because I don't know what to do with it in the context of Trinidad tr:fileDownloadActionListener api. – itro Jun 17 '20 at 08:06
  • 2
    It isn't an alternative. It's the only thing here that produces PDF, and you are either commenting it out or throwing it away. – user207421 Jun 17 '20 at 09:39
  • @MarquisofLorne Trinidad API doesn't require creating PDF or at least I didn't find any documentation on this issue. The only ref that I have is https://myfaces.apache.org/trinidad/trinidad-api/tagdoc/tr_fileDownloadActionListener.html – itro Jun 17 '20 at 12:51
  • 1
    Of course it doesn't, but *you* do. Otherwise what exactly is your question about? – user207421 Jun 18 '20 at 00:25

1 Answers1

2

I did change the backend as below according to what people mentioned in the command above, now I can read it with PDF reader. Thanks to all of you.

public void downloadMehr(FacesContext context, OutputStream out) throws IOException
    {
        String fetchedXmlMessage = getFetchedXmlMessage();
        XmlPrettifier prettifier = XmlPrettifierFactory.getInstance();
        prettyXmlMessage = prettifier.makePretty(fetchedXmlMessage);

        // create pdf from string
        PdfCreator pdfCreator = new PdfCreator( prettyXmlMessage);
        File pdfFile = pdfCreator.create();

        FileInputStream inStream = new FileInputStream(pdfFile);
        byte[] buffer = new byte[4096];
        int bytesRead = -1;

        while ((bytesRead = inStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
        }

        inStream.close();
        outputStream.close();
    }
itro
  • 7,006
  • 27
  • 78
  • 121