2017-03-13 1 views
2

Considérez une requête SQL dont le résultat sera écrit dans le fichier pdf.Problème PDFBox lors de la création dynamique d'une nouvelle page

Je peux écrire le contenu (récupéré de la requête) dans le pdf avec succès mais il tronque le contenu s'il franchit la limite maximum d'une page. Cela signifie qu'une seule page est créée. En écrivant dans le pdf (via PDFBox), comment savoir que nous avons atteint la fin d'une page, afin que nous puissions déclencher doc.addPage(page); une fois que nous savons dynamiquement que nous avons atteint le point final de la page.

Voici le code ci-dessous:

public PDDocument processPdf(Class1 objectClass1) { 
    String text; 
    int count; 
    //New Document is created 
    PDDocument doc = new PDDocument(); 
    List<Class1Questions> objectClass1Questions; 
    Class2 objectClass2; 
    try { 
     float fontSize = 12; 
     float margin = 72; 
     float leading = 1.5f * fontSize; 
     PDFont font = PDType1Font.HELVETICA; 
     PDPage page = new PDPage(); 
     page.setMediaBox(PDRectangle.A4); 
     PDRectangle pageSize = page.getMediaBox(); 
     float startX = pageSize.getLowerLeftX() + margin; 
     float startY = pageSize.getUpperRightY() - margin; 
     //First page is added 
     doc.addPage(page); 
     List<String> lines; 
     PDPageContentStream contentStream = new PDPageContentStream(doc, page); 
     contentStream.setFont(font, fontSize); 
     contentStream.beginText(); 
     //The resultset gets collected and written in PDF. 
     text = objectClass1.getClass1Name(); 
     lines = spacing(text, margin, font, pageSize); 
     contentStream.newLineAtOffset(startX, startY); 
     contentStream.showText("Class1: "); 
     for (String line : lines) { 
      contentStream.showText(line); 
      contentStream.newLineAtOffset(0, -leading); 
     } 
     List<Class1Version> versionList = objectClass1.getClass1Versions(); 
     for (Class1Version version : versionList) { 

      String versionNum = Long.toString(version.getClass1VersionNumber()); 
      contentStream.showText("Version: " + versionNum); 

      contentStream.newLineAtOffset(0, -leading); 
      objectClass1Questions = version.getClass1Questions(); 
      count = 0; 
      for (Class1Questions objectClass1Question : objectClass1Questions) { 
       count++; 
       objectClass2 = objectClass1Question.getQuestion(); 
       String question = objectClass2.getQuestionDesc(); 
       lines = spacing(question, margin, font, pageSize); 
       contentStream.showText("Q" + count + ": "); 
       for (String line : lines) { 
        contentStream.showText(line); 
        contentStream.newLineAtOffset(0, -leading); 
       } 
       contentStream.newLineAtOffset(0, -leading); 
      } 
     } 
     contentStream.endText(); 
     contentStream.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return doc; 
    } 

    public List<String> spacing (String text, float margin, PDFont font, PDRectangle pageSize) throws IOException { 
    int lastSpace = -1; 
    List<String> lines = new ArrayList<String>(); 
    float fontSize = 25; 
    float width = pageSize.getWidth() - 2*margin; 

    while (text.length() > 0) 
    { 
     int spaceIndex = text.indexOf(' ', lastSpace + 1); 
     if (spaceIndex < 0) 
      spaceIndex = text.length(); 
     String subString = text.substring(0, spaceIndex); 
     float size = fontSize * font.getStringWidth(subString)/1000; 
     System.out.printf("'%s' - %f of %f\n", subString, size, width); 
     if (size > width) 
     { 
      if (lastSpace < 0) 
       lastSpace = spaceIndex; 
      subString = text.substring(0, lastSpace); 
      lines.add(subString); 
      text = text.substring(lastSpace).trim(); 
      System.out.printf("'%s' is line\n", subString); 
      lastSpace = -1; 
     } 
     else if (spaceIndex == text.length()) 
     { 
      lines.add(text); 
      System.out.printf("'%s' is line\n", text); 
      text = ""; 
     } 
     else 
     { 
      lastSpace = spaceIndex; 
     } 
    } 
    return lines; 
} 
+2

Je ne comprends pas pourquoi c'est une question; vous êtes capable d'écrire des contenus. Ainsi, vous les mettez à des positions en Y. Parce que le haut d'une page est la hauteur, cela signifie que plus vous approchez du bas, plus votre valeur y est petite; et si c'est <0 alors vous ne le voyez plus. La seule explication que je peux trouver est que vous avez commencé avec y = 0 et n'avez pas remarqué que sur votre page tout était en sens inverse. –

+0

Mis à jour le message avec mon code existant. –

+1

Vous devrez introduire une variable dans laquelle vous noterez la coordonnée ** y ** actuelle, en la définissant à 'startY' quand vous faites' contentStream.newLineAtOffset (startX, startY) ', en la diminuant par' leading' chaque fois que vous faire 'contentStream.newLineAtOffset (0, -leading)', et vérifier dans ces situations, aussi, si cette valeur de la variable est trop petite (plus comme moins de 'marge'). – mkl

Répondre

1

Déclarez une variable totalheight, réglez la hauteur de marge;

float totalHeight = margin; 

Get hauteur de la police comme ci-dessous:

float fontHeight = font.getFontDescriptor().getFontBoundingBox() 
      .getHeight() 
      /1000 * fontSize; 

Mais il ne reviendra pas à la hauteur exacte, vous pouvez jouer avec elle pour obtenir de meilleurs résultats. obtenez alors a4 taille de la page:

float a4Height= PDRectangle.A4.getHeight(); 

Chaque fois que vous entrez une nouvelle augmentation de la ligne hauteur totale et vérifier si elle dépasse le a4Height compte tenu de la hauteur de la marge

totalHeight += fontHeight; 
if(totalHeight+margin>=a4Height){ 
    page = new PDPage(); 
    doc.addPage(page); 
    totalHeight = margin; 
} 
+1

Vous devez réinitialiser votre variable totalHeight. –

+0

@TilmanHausherr Merci. J'ai mis à jour la réponse – AhmetRasitBekar

+0

@Pratim Singha, s'il vous plaît appuyez sur la coche si la réponse a résolu votre problème, ou dire ce qui s'est passé si ce n'était pas le cas. –

1

J'ai essayé de prendre la solution donnée par @AhmetRasitBekar et la solution mentionnée dans le commentaire de @mkl.

  1. Introduisez une variable dans laquelle vous notez la coordonnée y actuelle, en la réglant sur startY. Considérez la variable comme yCordinate.
  2. Calculées la hauteur de la police

    float fontHeight = font.getFontDescriptor().getFontBoundingBox().getHeight()/1000 * fontSize;

  3. Chaque fois que le contenu du texte sont écrits dans le fichier pdf, la variable yCordinate sera diminuée par fontHeight.

    contentStream.showText(line); yCordinate -= fontHeight;

  4. Chaque fois qu'une nouvelle ligne a été ajoutée, la yCordinate est diminué de leading

contentStream.newLineAtOffset(0, -leading); yCordinate -= leading;

  1. Chaque fois que la yCordinate est accédé et modifié, une instruction conditionnelle est écrite pour vérifier si t il yCordinate <= 10. Si oui, alors le code ci-dessous.
if(yCordinate <= 10){ 
    page = new PDPage(); //new page created 
    page.setMediaBox(PDRectangle.A4); 
    pageSize = page.getMediaBox(); 
    startX = pageSize.getLowerLeftX() + margin; //Calculate the X and Y cordinate 
    startY = pageSize.getUpperRightY() - margin; 
    doc.addPage(page); //Add the page to the PDDocument 
    yCordinate = startY; //Reset the yCordinate with the new Y cordinate 
    contentStream.endText(); //End and Close the previous contentStream 
    contentStream.close(); 
    contentStream = new PDPageContentStream(doc, page); //Create a new contentStream and use it further 
    contentStream.setFont(font, fontSize); 
    contentStream.beginText(); 
    contentStream.newLineAtOffset(startX, startY); 
} 

Cela va créer dynamiquement des pages dans le pdf si le contenu dépasse la limite de page PDF.