3

I am trying to export an HTML page into a PDF using Flying Saucer. For some reason, the pages have a large white space after the header (id = "divTemplateHeaderPage1") divisions. The jsFiddle link to my HTML code that is being used by PDF renderer: https://jsfiddle.net/Sparks245/uhxqdta6/.

Below is the Java code used for rendering the PDF (Test.html is the same HTML code in the fiddle) and rendering only one page.

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.HTTP;
import org.json.JSONException;
import org.json.*;
import org.json.simple.JSONArray;
import org.json.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

import org.json.simple.parser.*;
import org.xhtmlrenderer.pdf.ITextRenderer;

import com.lowagie.text.DocumentException;
import com.lowagie.text.List;
import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiNilLoader.Array;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;


@WebServlet("/PLPDFExport")
public class PLPDFExport extends HttpServlet 
{

    //Option for Serialization
    private static final long serialVersionUID = 1L;

    public PLPDFExport() 
    {
        super();
    }

    //Get method
    protected void doGet(HttpServletRequest request, 
                         HttpServletResponse response) 
                   throws ServletException, 
                          IOException 
    {

    }

    //Post method
    protected void doPost(HttpServletRequest request, 
                          HttpServletResponse response) 
                   throws ServletException, 
                          IOException
    {
            StringBuffer jb = new StringBuffer();
            String line = null;
            int Pages; 
            String[] newArray = null;

            try 
            {
                BufferedReader reader = request.getReader();
                while ((line = reader.readLine()) != null)
                {   jb.append(line);
                }
            } catch (Exception e) { /*report an error*/ }


            try 
            {
                JSONObject obj = new JSONObject(jb.toString());

                Pages = obj.getInt("Pages");

                newArray = new String[1];  
                for(int cnt = 1; cnt <= 1; cnt++)
                {  

                    StringBuffer  buf = new StringBuffer();

                    String base = "C:/Users/Sparks/Desktop/";

                    buf.append(readFile(base + "Test.html"));

                    newArray[0] = buf.toString(); 
                }
            } 


            catch (JSONException e)
            {
                // crash and burn
                throw new IOException("Error parsing JSON request string");
            }


            //Get the parameters

            OutputStream os = null;
            try {

                final File outputFile = File.createTempFile("FlyingSacuer.PDFRenderToMultiplePages", ".pdf");
                os = new FileOutputStream(outputFile);

                ITextRenderer renderer = new ITextRenderer();


                // we need to create the target PDF
                // we'll create one page per input string, but we call layout for the first

                renderer.setScaleToFit(true);
                renderer.isScaleToFit();
                renderer.setDocumentFromString(newArray[0]);

                renderer.layout();
                try {
                    renderer.createPDF(os, false);
                } catch (DocumentException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                // each page after the first we add using layout() followed by writeNextDocument()
                for (int i = 1; i < newArray.length; i++) {
                    renderer.setScaleToFit(true);
                    renderer.isScaleToFit();
                    renderer.setDocumentFromString(newArray[i]);
                    renderer.layout();
                    try {
                        renderer.writeNextDocument();
                    } catch (DocumentException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }

                // complete the PDF
                renderer.finishPDF();

                System.out.println("PDF Downloaded to " + outputFile );
                System.out.println(newArray[0]);

            }
            finally {
                if (os != null) {
                    try {
                        os.close();
                    } catch (IOException e) { /*ignore*/ }
                }
            }

            //Return
            response.setContentType("application/json");
            response.setCharacterEncoding("UTF-8");
            response.getWriter().write("File Uploaded");
    }

    String readFile(String fileName) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader(fileName));
        try {
            StringBuilder sb = new StringBuilder();
            String line = br.readLine();

            while (line != null) {
                sb.append(line);
                sb.append("\n");
                line = br.readLine();
            }
            return sb.toString();
        } finally {
            br.close();
        }
    }

}

The link for exported PDF: https://drive.google.com/file/d/13CmlJK0ZDLolt7C3yLN2k4uJqV3TX-4B/view?usp=sharing

I tried adding css properties like page-break-inside: avoid to the header divisions but it didn't work. Also I tried adding absolute positions and top margins to the body division (id = "divTemplateBodyPage1") just below the header div, but the white space continues to exist.

Any suggestions would be helpful.

Sparks
  • 115
  • 1
  • 9

1 Answers1

0

Please take a look at the metadata of your PDF:

enter image description here

You are using an old third party tool that is not endorsed by iText Group, and that uses iText 2.1.7, a version of iText dating from 2009 that should no longer be used.

It would probably have been OK to complain and to write "My code isn't working" about 7 years ago, but if you would use the most recent version of iText, the result of converting your HTML to PDF would look like this:

enter image description here

I only needed a single line of code to get this result:

HtmlConverter.convertToPdf(new File(src), new File(dest));

In this line src is the path the the source HTML and dest is the path to the resulting PDF.

I only had to apply one minor change to your HTML. I change the @page properties like this:

@page {
  size: 27cm 38cm;
  margin: 0.2cm;
}

If I hadn't changed this part of the CSS, the page size would have been A4, and in that case, not all the content would have fitted the page. I also added a small margin because I didn't like the fact that the border was sticking to close to the sides of the page.

Morale: don't use old versions of libraries! Download the latest version of iText and the pdfHTML add-on. You need iText 7 core and the pdfHTML add-on. You might also want to read the HTML to PDF tutorial.

Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165
  • Okay. I am using pdfHTML of iText7 now with a trial version license key. This is my java code: https://ideone.com/fork/r2AWfq and get this error: Exception in thread "main" java.lang.ClassCastException: java.lang.Float cannot be cast to com.itextpdf.layout.property.UnitValue. Should I make any changes to my Test.html file. – Sparks Dec 16 '17 at 18:10
  • That's strange. I don't have that problem and I use iText 7.1.0 and pdfHTML 2.0.0. I'll make a ticket in our ticketing system. I'll add the HTML I use to my answer. – Bruno Lowagie Dec 16 '17 at 23:11
  • As it turns out, I can't add the HTML to my answer, not even if I remove the images. The number of characters allowed in an answer is too small. – Bruno Lowagie Dec 16 '17 at 23:17
  • @Bruno in the attempt you actually removed the image URLs. – mkl Dec 16 '17 at 23:26
  • In any case, @Sparks could you send your HTML and the error message to the mail address that was used to send the key? That way, the people at iText will make a ticket out of it on their closed ticketing system. Since I can't reproduce the problem, I can't help you. I need something that doesn't work before I can fix it. – Bruno Lowagie Dec 17 '17 at 00:02
  • @BrunoLowagie I figured out the issue (wasn't creating a maven project before instead downloaded the source code from github). I am able to export the PDF now same as yours. Wanted to know how to resolve the alignment of text just above disclaimer which is shifted to the left (id = "IndexAbbr55" in html code). The align attribute has been set to "right" though – Sparks Dec 17 '17 at 07:02
  • Also, some part of the disclaimer text "The information contained in this document is not intended to ..." is flowing out of the PDF border. Let me know if there is any change I should make in html file or any scaling function that can be used from iText – Sparks Dec 17 '17 at 07:09
  • @Sparks I don't have time to look at this right now, but when I look at the HTML in a browser, there is a problem at the bottom of the page too, so I think there is some problem with the CSS for that bottom part. – Bruno Lowagie Dec 17 '17 at 15:28
  • @BrunoLowagie yes I have corrected the HTML code (jsFiddle code: https://jsfiddle.net/Sparks245/uhxqdta6/2/) now. The UI looks fine in browser. The PDF export still has the same formatting at the bottom. – Sparks Dec 18 '17 at 11:12
  • Could you send the HTML and a description of the problem to the address from which you obtained the trial license. I don't have much time to answer this personally. – Bruno Lowagie Dec 19 '17 at 16:53
  • @BrunoLowagie. I have mailed the html, Java code and the PDF file to marketing@itextpdf.com and sales@itextpdf.com. Thanks – Sparks Dec 21 '17 at 06:04
  • OK, I see that a ticket was created for it: https://jira.itextsupport.com/browse/SUP-2582 (you don't have access to this ticket, but maybe in the future you will). – Bruno Lowagie Dec 21 '17 at 07:43
  • The ticket was just closed as a duplicate of https://jira.itextsupport.com/browse/TSALES-3021 which has the same content, but it was created by someone at sales. The ticket has been assigned to an iText engineer. – Bruno Lowagie Dec 21 '17 at 16:53
  • https://mvnrepository.com/artifact/org.xhtmlrenderer/flying-saucer-pdf latest version as of now 9.1.20 generating "iText 2.1.7 by 1T3XT", whereas https://mvnrepository.com/artifact/com.itextpdf/html2pdf latest 3.0.3 generating "iText 7.1.14...." – Satish Patro Mar 08 '21 at 14:09