2017-12-16 5 views
3

Ich versuche, eine HTML-Seite in eine PDF-Datei mit Flying Saucer zu exportieren. Aus irgendeinem Grund haben die Seiten einen großen Leerraum nach den Kopfzeilen (id = "divTemplateHeaderPage1") Divisionen. Die jsFiddle-Verknüpfung zu meinem HTML-Code, der vom PDF-Renderer verwendet wird: https://jsfiddle.net/Sparks245/uhxqdta6/.Riesige Leerraum nach Kopfzeile in PDF mit Flying Saucer

Unten ist der Java-Code für das Rendern der PDF (Test.html ist der gleiche HTML-Code in der Geige) und das Rendern nur einer Seite.

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(); 
     } 
    } 

} 

Der Link für exportierte PDF: https://drive.google.com/file/d/13CmlJK0ZDLolt7C3yLN2k4uJqV3TX-4B/view?usp=sharing

Ich habe versucht, CSS-Eigenschaften wie page-break-inside ergänzt: vermeiden den Kopf Divisionen, aber es hat nicht funktioniert. Ich habe auch versucht, absolute Positionen und obere Ränder zu der Körperabteilung (ID = "divTemplateBodyPage1") direkt unter dem Header div hinzuzufügen, aber der weiße Raum besteht weiter.

Alle Vorschläge wären hilfreich.

Antwort

0

Bitte nehmen Sie sich einen Blick auf den Metadaten Ihres PDF:

enter image description here

Sie verwenden ein altes Drittes Werkzeug, das ist nicht von iText Gruppe unterstützt, und das nutzt iText 2.1.7, eine Version von iText aus dem Jahr 2009 that should no longer be used.

Wahrscheinlich OK gewesen wäre beschweren und zu schreiben ca. 7 Jahre „Mein Code funktioniert nicht“ vor, aber wenn Sie sich die neueste Version von iText verwenden, um das Ergebnis Ihrer HTML-Konvertierung PDF würde wie folgt aussehen:

enter image description here

ich nur eine einzige Zeile Code erforderlich, um dieses Ergebnis zu erhalten:

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

In dieser Zeile steht src für den Pfad der Quell-HTML und dest für den Pfad zur resultierenden PDF.

Ich musste nur eine geringfügige Änderung an Ihrem HTML anwenden. Ich wechsle die @page Eigenschaften wie folgt aus:

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

Wenn ich nicht diesen Teil der CSS geändert hätte, wäre die Seitengröße A4 gewesen sein, und in diesem Fall nicht der gesamte Inhalt würde die Seite eingebaut haben. Ich fügte auch einen kleinen Rand hinzu, weil ich nicht mochte, dass die Grenze dicht an den Seiten der Seite klebte.

Moral: Verwenden Sie keine alten Versionen von Bibliotheken! Download the latest version of iText and the pdfHTML add-on. Sie benötigen iText 7 core und die pdfHTML add-on. Vielleicht möchten Sie auch die HTML to PDF tutorial lesen.

+0

Okay. Ich benutze pdfHTML von iText7 jetzt mit einem Testversion Lizenzschlüssel. Das ist mein Java-Code: https://ideone.com/fork/r2AWfq und bekomme diesen Fehler: Ausnahme im Thread "main" java.lang.ClassCastException: java.lang.Float kann nicht in com.itextpdf.layout umgewandelt werden. property.UnitValue. Sollte ich Änderungen an meiner Test.html-Datei vornehmen? – Sparks

+0

Das ist seltsam. Ich habe dieses Problem nicht und ich benutze iText 7.1.0 und pdfHTML 2.0.0.Ich werde ein Ticket in unserem Ticketsystem machen. Ich füge den HTML-Code hinzu, den ich für meine Antwort verwende. –

+0

Wie sich herausstellt, kann ich den HTML-Code nicht zu meiner Antwort hinzufügen, selbst wenn ich die Bilder entferne. Die Anzahl der Zeichen in einer Antwort ist zu klein. –

Verwandte Themen