2017-03-13 42 views
2

考慮一個SQL查詢,其結果將寫入pdf中。動態創建新頁面時出現PDFBox問題

我可以成功地在pdf中寫入內容(從查詢中檢索),但如果內容超過一頁的最大限制,它會截斷內容。這意味着,只有一個頁面被創建。

在寫入pdf(通過PDFBox)時,如何知道我們已經到達頁面的末尾,以便在動態地知道我們已經到達頁面的終點時觸發doc.addPage(page);

這裏是下面的代碼:

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

我不明白爲什麼這是一個問題;你可以寫內容。因此你把它們放在Y位置。因爲頁面的頂部是高度,這意味着越接近底部,y值越小;如果它<0,那麼你不再看到它。我能想出的唯一解釋是,你從y = 0開始,並沒有注意到你的頁面上的所有內容都是相反的。 –

+0

用我現有的代碼更新了帖子。 –

+1

您必須引入一個變量,在該變量中您記錄當前的** y **座標,並在您執行contentStream.newLineAtOffset(startX,startY)時將其設置爲'startY',並在每次您用'leading'做'contentStream.newLineAtOffset(0,-leading)',然後檢查這些情況,也就是說,這個變量值是否太小(大部分小於'margin')。 – mkl

回答

1

聲明一個totalHeight變量,將其設置爲餘量高度;

float totalHeight = margin; 

取得字體高度象下面這樣:

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

但它不會返回精確的高度,你可以用它玩,以獲得更好的效果。 然後得到一張A4紙大小:

float a4Height= PDRectangle.A4.getHeight(); 

每當你進入一個新的生產線增加的總高度,檢查它是否超出a4Height考慮餘量高度

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

您需要重置totalHeight變量。 –

+0

@TilmanHausherr謝謝。我更新了答案 – AhmetRasitBekar

+0

@Pratim Singha,如果答案解決了您的問題,請按複選標記,或者如果答案不是,請說出發生了什麼。 –

1

我試圖把給出的解決方案通過@AhmetRasitBakar和@mkl評論中提到的解決方案。

  1. 引入一個變量,其中記下當前y座標, 將其設置爲startY。考慮這個變量爲yCordinate
  2. 計算字體高度

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

  3. 每個文本內容被寫入到PDF文件時,該變量 yCordinate將由fontHeight降低。

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

  4. 每一個新行已被添加時,yCordinateleading

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

降低
  • 每次yCordinate被訪問和更改,寫入條件語句 以檢查t他yCordinate <= 10。如果 是,那麼下面的代碼。如果內容超過了PDF頁面的限制
  • 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); 
    } 
    

    這將動態創建的PDF頁面。