Hot questions for Using PDFBox in pdf reader

Top Java Programmings / PDFBox / pdf reader

Question:

Read a pdf file from url with using of PDFbox, below jave code its perfect to read a pdf and stored in project location.

String pdfPageCount = 17;
String pdfUrl = "abc.org/invoicepdf.pdf?Range=1";
URL pdfDownload = new URL(pdfUrl);
connectionGet = (HttpsURLConnection) pdfDownload.openConnection();
String authorizationHeader1 = "Bearer " + getToken;
connectionGet.setRequestProperty("Authorization", authorizationHeader1);
connectionGet.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connectionGet.setRequestMethod("GET");
int responseCode = connectionGet.getResponseCode();
    if (responseCode != 404) {
        PDDocument pd = new PDDocument();
        InputStream inputstreamFinal1 = connectionGet.getInputStream();
        PDDocument load = PDDocument.load(inputstreamFinal1);                        
        load.save("CopyOfInvoice1.pdf");
    }

My next step

I want to looping the process based on the pdfPageCount value, currently i do hard-coded the page count in 1 in the pdfUrl (/invoicepdf.pdf?Range=1)

Expected:

Read all the 17 pages and save into an single pdf file


Answer:

Here's some code, based on the PDFMergerExample that is mentioned in the comments. Note that I haven't checked if your URL retrieval code is correct.

List<InputStream> sources = new ArrayList<InputStream>();
int pdfPageCount = 17;
try
{
    for (int p = 1; p <= pdfPageCount; ++p)
    {
        String pdfUrl = "abc.org/invoicepdf.pdf?Range=" + p;
        URL pdfDownload = new URL(pdfUrl);
        HttpsURLConnection connectionGet = (HttpsURLConnection) pdfDownload.openConnection();
        String authorizationHeader1 = "Bearer " + getToken;
        connectionGet.setRequestProperty("Authorization", authorizationHeader1);
        connectionGet.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        connectionGet.setRequestMethod("GET");
        int responseCode = connectionGet.getResponseCode();
        if (responseCode != 404)
        {
            sources.add(connectionGet.getInputStream());
        }
        else
        {
            //TODO error handling
            return;
        }
    }
    PDFMergerUtility pdfMerger = new PDFMergerUtility();
    pdfMerger.addSources(sources);
    pdfMerger.setDestinationFileName("CopyOfInvoice1.pdf");
    pdfMerger.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());
}
catch (IOException e)
{
     //TODO error handling
     return;
}
finally
{
    // cleanup
    for (InputStream source : sources)
    {
        IOUtils.closeQuietly(source);
    }   
}

Question:

i'm trying to make a simple pdf reader with Java and PDFBox; In my code i convert the pages in ImageIcon and then i set it in a JLabel, the JLabel is added to a ScrollPane so at the end i have a nice scrollable page.

For the first page (loaded by the constructor) it works fine, but when i try to load another page from the actionPerformed function the result is a blank page, even if the try-catch give no error.

public class PDFreader extends JFrame implements ActionListener {

    List<PDPage> Pages;
    int CurrentPage = 0;

    JButton Back, Next;
    JLabel Info, LabelImage;

    public PDFreader(String Title, PDDocument doc) throws IOException {

        this.setTitle(Title);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setExtendedState(JFrame.MAXIMIZED_BOTH);

        getContentPane().setLayout(new BorderLayout());

        Pages = doc.getDocumentCatalog().getAllPages();
        PDPage pag = (PDPage) Pages.get(CurrentPage);

        ImageIcon PageImage = new ImageIcon(pag.convertToImage());
        LabelImage = new JLabel(PageImage);

        JScrollPane scrollPane = new JScrollPane(LabelImage);

        Back = new JButton("Previous page");
        Next = new JButton("Next page");

        Back.setEnabled(false);
        if(Pages.size()==1)
            Next.setEnabled(false);

        Back.addActionListener(this);
        Next.addActionListener(this);

        JPanel p = new JPanel();
        p.setLayout(new GridLayout(1,2));
        p.add(Back);
        p.add(Next);

        Info = new JLabel("Page 1 of "+ Pages.size(), SwingConstants.CENTER);

        getContentPane().add(scrollPane, BorderLayout.CENTER);
        getContentPane().add(p, BorderLayout.NORTH);
        getContentPane().add(Info, BorderLayout.SOUTH);

        pack();
        setVisible(true);
    }




    @Override
    public void actionPerformed(ActionEvent Ev) {
        // TODO Auto-generated method stub
        if(Ev.getSource() == Next) {
            CurrentPage++;
        }
        if(Ev.getSource() == Back) {
            CurrentPage--;
        }

        if(CurrentPage == 0)
            Back.setEnabled(false);
        else
            Back.setEnabled(true);

        if(CurrentPage == Pages.size()-1)
            Next.setEnabled(false);
        else
            Next.setEnabled(true);          


        try {
            PDPage page = (PDPage) Pages.get(CurrentPage);
            ImageIcon PageImage = new ImageIcon(page.convertToImage());
            LabelImage.setIcon(PageImage);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();        

        }

        Info.setText("Pagina "+(CurrentPage+1)+" di "+ Pages.size());

    }
}

Is there a problem because i'm trying to load it in the actionPerformed? Any other tips?


Answer:

You are closing the document too early, that is why. I was able to reproduce the effect you get by closing the document after calling

new PDFReader("Title", doc);

So one solution would be e.g. opening the document within the JPanel constructor instead of passing it as a parameter as you do now (pass the file instead), and close it when the JPanel is closing by adding this:

addWindowListener(new java.awt.event.WindowAdapter()
{
    @Override
    public void windowClosing(java.awt.event.WindowEvent evt)
    {
        try
        {
            document.close();
        }
        catch (IOException ex)
        {
        }
    }
});

document need to be a local final variable within your PDFReader class.