2011-11-24 97 views
18

我意識到這個問題已被問及之前(我看了所有的解決方案,並嘗試所有),但我仍然試圖生成一個PDF文檔的頁眉和頁腳在每一頁上重複。生成頁眉/頁腳與飛碟(xHTMLRenderer)和iText

我正在使用flying saucer R8與iText2.0.8我已經嘗試了很多不同的方法來使它工作,但目前爲止無濟於事。我測試過的一些方法是https://gist.github.com/626264,使用運行元素和邊距框http://pigeonholdings.com/projects/flyingsaucer/R8/doc/guide/users-guide-R8.html#xil_40(css3功能),飛碟r7指南,不適用於r8 http://today.java.net/pub/a/today/2007/06/26/generating-pdfs-with-flying-saucer-and-itext.html#page-specific-features,長期以來許多其他方法不適用於我。

我的標題div包含2個其他div與圖像和我的頁腳只是頁碼。這個html被放入一個叫做buf的StringBuffer

buf.append("<head>"); 
    buf.append("<title>blabla</title> "); 
    buf.append("<style type='text/css' media='print'> "); 
    buf.append("@page { size:8.5in 11in; padding:1em; @bottom-left { content: element(footer); } } "); 
    buf.append("#footer { font-size: 90%; font-style: italic; position: running(footer); top: 0; left: 0; }"); 
    buf.append("#pagenumber:before { content: counter(page); } "); 
    buf.append("#pagecount:before { content: counter(pages); } "); 
buf.append("</style></head>"); 
buf.append("<body>"); 
buf.append("<div class='header' style='clear:both;'>"); 
    buf.append("<div id='moneyLogo' style='float:left'>"); 
    buf.append("<img src='logo.jpg' alt='Some alt text' />"); 
    buf.append("</div>"); 
    buf.append("<div id='canLogo' style='float:right'>"); 
    buf.append("<img src='someImg.gif' alt='alt text' />"); 
    buf.append("</div>"); 
    buf.append("<h3 style='text-align:center; clear:both;'>alt text</h3>"); 
    buf.append("<div style='text-align:center;'>"); 
    buf.append("Some texy text"); 
    buf.append("<br />");); 
    buf.append("</div>"); 
    buf.append("</div><br /><br />"); 
buf.append("<div id='footer'> Page <span id='pagenumber'/> of <span id='pagecount'/> </div>"); 

    buf.append("</body>"); 
    buf.append("</html>"); 

我的pdf生成很好,除了頭只出現在第一頁上,頁腳只出現在最後一頁的底部。當我通過W3C驗證器的HTML它出來很好,但是當我用他們的CSS驗證器它說,他們在線路分析錯誤@page { size:8.5in 11in; padding:1em; @bottom-left { content: element(footer); } }

據我所知道的所有指南我讀這很好。我還聽說W3C CSS驗證器對於CSS3規範是不完整的,所以我認爲它是驗證者錯了。

如果有人可以給我到哪裏尋找或想法,就會使我一週:)

附:一些技巧必須使用飛碟R8和/或iText的2.0.8

+1

對未來用戶留下評論:如果頁腳未在flyingsaucer的所有頁面上運行,請確保頁腳元素是BEFORE內容,這與正常的HTML頁面不同。您可以通過@Giovanni查看下面的示例,其中顯示頁眉和頁腳在內容之前。你的代碼是正確的,只是頁眉和頁腳必須放在內容之前,而且非常直觀。 –

回答

26

這裏是一個工作示例:

package com.sg2net.test; 

import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 

import org.xhtmlrenderer.pdf.ITextRenderer; 

import com.lowagie.text.DocumentException; 

public class XHTMLRenderer8 { 

    /** 
    * @author Giovanni Cuccu 
    */ 
    public static void main(String[] args) throws FileNotFoundException, DocumentException { 
     ITextRenderer renderer = new ITextRenderer(); 
     String content="<html><head><style>\n" + 
      "div.header {\n" + 
      "display: block; text-align: center;\n" + 
      "position: running(header);}\n" + 
      "div.footer {\n" + 
      "display: block; text-align: center;\n" + 
      "position: running(footer);}\n" + 
      "div.content {page-break-after: always;}" + 
      "@page { @top-center { content: element(header) }}\n " + 
      "@page { @bottom-center { content: element(footer) }}\n" + 
      "</style></head>\n" + 
      "<body><div class='header'>Header</div><div class='footer'>Footer</div><div class='content'>Page1</div><div>Page2</div></body></html>"; 
     renderer.setDocumentFromString(content); 
     renderer.layout(); 
     renderer.createPDF(new FileOutputStream("test.pdf")); 

    } 

} 

這是使用以下XHTML文檔

<html> 
<head> 
<style> 
div.header { 
    display: block; text-align: center; 
    position: running(header); 
} 
div.footer { 
    display: block; text-align: center; 
    position: running(footer); 
} 
div.content {page-break-after: always;} 
@page { 
    @top-center { content: element(header) } 
} 
@page { 
    @bottom-center { content: element(footer) } 
} 
</style> 
</head> 
<body> 
    <div class='header'>Header</div> 
    <div class='footer'>Footer</div> 
    <div class='content'>Page1</div> 
    <div>Page2</div> 
</body> 
</html> 
+0

謝謝,我結束了使用這種方法,它完全適合我:) – flyingCaffine

+0

這正是我所尋找的。謝謝! – Alex

1

爲iText的使用烏爾pdfwriter使用下面的一個java的結帳這個

public class HeaderAndFooter extends PdfPageEventHelper { 

public void onEndPage (PdfWriter writer, Document document) { 
    Rectangle rect = writer.getBoxSize("art"); 
    switch(writer.getPageNumber() % 2) { 
    case 0: 
     ColumnText.showTextAligned(writer.getDirectContent(), 
       Element.ALIGN_RIGHT, new Phrase("even header"), 
       rect.getBorderWidthRight(), rect.getBorderWidthTop(), 0); 
     break; 
    case 1: 
     ColumnText.showTextAligned(writer.getDirectContent(), 
       Element.ALIGN_CENTER, new Phrase(String.format("%d", writer.getPageNumber())), 
       300f, 62f, 0); 
     break; 
    } 
    ColumnText.showTextAligned(writer.getDirectContent(), 
      Element.ALIGN_CENTER, new Phrase(String.format("%d", writer.getPageNumber())), 
      (2f + 4f)/2, 2f - 18, 0); 
} 
} 

HeaderAndFooter event = new HeaderAndFooter(); 
     writer.setPageEvent(event); 
+1

我之前使用過類似的東西,但它沒有很好地與我的飛碟代碼集成。如果你只使用沒有飛碟的iText,那麼它仍然很有用:) – flyingCaffine

10

經過大量研究和測試後,我纔想出了一個真正有效的解決方案。

您可以控制:

- 通過編輯margin-top標題高度;

- 通過編輯頁邊距底部的頁腳高度;

- 通過編輯div.content寬度的內容寬度。

頁碼顯示在頁腳處。

見下面的代碼:

<html> 
<head> 
<style> 

@page{ 

    @bottom-left {     
     content: element(footer); 
     vertical-align: top; 
     padding-top: 10px; 
/*  border: solid red; */ 
    } 

    @top-right { 
     content: element(header); 
     vertical-align: bottom; 
     padding-bottom: 10px; 
/*   border: solid green; */ 
    } 

    size: A4 portrait; 
    margin-top:5.5cm; 
    margin-left:3cm; 
    margin-right:2cm; 
    margin-bottom:3.3cm; 
} 

div.header { 
    display: block;      
    position: running(header); 
    border-bottom: 1px solid black; 
} 

div.footer { 
    margin-top: 0.5cm; 
    display: block; 
    position: running(footer); 
    border-top: 1px solid black; 
} 

div.content { 
/* border: solid purple; */ 
    display: block; 
    width: 15.4cm; 
    text-align: justify; 
} 

#pagenumber:before { 
    content: counter(page); 
} 

#pagecount:before { 
    content: counter(pages); 
} 

</style> 
</head> 
<body> 

    <div class="header"> 
     This is the header that will repeat on every page at top 
    </div> 

    <div class="footer" > 
     <p>This is the footer that will repeat on every page at bottom</p> 
     <p>Page <span id="pagenumber"></span> of <span id="pagecount"></span></p>/ 
    </div> 

    <div class="content"> 
     <p>This is the content</p><p>This is the content</p><p>This is the content</p> 
     <p>This is the content</p><p>This is the content</p><p>This is the content</p> 
     <p>This is the content</p><p>This is the content</p><p>This is the content</p> 
     <p>This is the content</p><p>This is the content</p><p>This is the content</p> 
     <p>This is the content</p><p>This is the content</p><p>This is the content</p> 
     <p>This is the content</p><p>This is the content</p><p>This is the content</p> 
     <p>This is the content</p><p>This is the content</p><p>This is the content</p> 
     <p>This is the content</p><p>This is the content</p><p>This is the content</p> 
     <p>This is the content</p><p>This is the content</p><p>This is the content</p> 
     <p>This is the content</p><p>This is the content</p><p>This is the content</p> 
     <p>This is the content</p><p>This is the content</p><p>This is the content</p> 
     <p>This is the content</p><p>This is the content</p><p>This is the content</p> 
     <p>This is the content</p><p>This is the content</p><p>This is the content</p> 
    </div> 

</body> 
</html> 

希望它可以幫助!

+0

謝謝!該解決方案爲我工作。 –