2013-02-08 388 views
9

感謝您的幫助......使用iText,如何使用CssResolver和CssFile將css應用於我的PDF文檔?

問題

雖然轉換的HTML表格標籤/段(我已經轉換成字符串)轉換成PDF文檔...

我能夠成功 CSS樣式應用於使用這種技術的PDF文檔...

CSSResolver cssResolver = XMLWorkerHelper.getInstance().getDefaultCssResolver(false); 
cssResolver.addCss("td {border-right: white .1px solid;}", true); 

但是,我不成功應用CSS使用現有的CSS文件的PDF文檔(即使用CssFile對象),是這樣的...

CSSResolver cssResolver = new StyleAttrCSSResolver(); 
InputStream csspathtest = Thread.currentThread().getContextClassLoader().getResourceAsStream("styles/itextweb.css");    
CssFile cssfiletest = XMLWorkerHelper.getCSS(csspathtest); 
cssResolver.addCss(cssfiletest);    

...我一直沒能得到這個工作,而且不知道是什麼問題是...我得到...

Java.io.IOException The document has no pages 

問:

如何正確使用CssFile與CssResolver應用CSS樣式 - 即從現有的「的CSS」的文件 - 到我的PDF文件? (什麼是錯的,我利用iText做到這一點的呢?)

(再次感謝您有這方面的幫助/指導)

============= ====下面是更詳細的信息===================

Java 6,JSF(Mojarra)2.1.11,Primefaces v3.4.2,itextpdf v5 .3.4,xmlworker V1.2.1

這是有問題的 「printPDF」 功能...

public void createPDF() throws DocumentException, CssResolverException 
{ 
    FacesContext context = FacesContext.getCurrentInstance(); 
    ExternalContext econtext = context.getExternalContext(); 

    try 
    { 
     String htmlstring = context.getExternalContext().getRequestParameterMap().get("testForm:htmlstring"); 

     InputStream is = new ByteArrayInputStream(htmlstring.getBytes());    
     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 

     // step 1 
     Document document = new Document(); 

     // step 2 
     PdfWriter writer = PdfWriter.getInstance(document, baos); 

     writer.setInitialLeading(12.5f); 

     // step 3 
     document.open(); 

     HtmlPipelineContext htmlContext = new HtmlPipelineContext(null); 

     htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory()); 

     // CSS 
     CSSResolver cssResolver = new StyleAttrCSSResolver(); 
     InputStream csspathtest = Thread.currentThread().getContextClassLoader().getResourceAsStream("styles/itextweb.css");    
     CssFile cssfiletest = XMLWorkerHelper.getCSS(csspathtest); 
     cssResolver.addCss(cssfiletest);    

     Pipeline<?> pipeline = new CssResolverPipeline(cssResolver, new HtmlPipeline(htmlContext, new PdfWriterPipeline(document, writer))); 

     XMLWorker worker = new XMLWorker(pipeline, true); 
     XMLParser p = new XMLParser(worker); 
     p.parse(is); //new FileInputStream("results/demo2/walden.html")); 

     // step  
     document.close(); 

     //post back... 
     HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse(); 
     response.setContentType("application/pdf"); 
     response.setHeader("Expires", "0"); 
     response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");   
     response.setHeader("Content-Type", "application/pdf"); 
     response.setHeader("Content-disposition","attachment;filename=file.pdf"); 
     response.setContentLength(baos.size()); 
     OutputStream os = response.getOutputStream(); 
     baos.writeTo(os); 
     os.flush(); 
     os.close(); 
     context.responseComplete(); 
    } 
    catch (FileNotFoundException e) 
    { 
     e.printStackTrace(); 
    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 
    catch (DocumentException e) 
    { 
     e.printStackTrace(); 
    } 
} 

這是包含HTML表格內容的網頁進行語法分析,以PDF格式(即,ID = 「表1」)...

<?xml version='1.0' encoding='UTF-8' ?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:ui="http://java.sun.com/jsf/facelets" 
     xmlns:h="http://java.sun.com/jsf/html" 
     xmlns:f="http://java.sun.com/jsf/core" 
     xmlns:c="http://java.sun.com/jsp/jstl/core" 
     xmlns:p="http://primefaces.org/ui"> 
    <f:view contentType="text/html"> 
     <h:head> 
      <title>test html-to-pdf with itext...</title> 
      <meta charset="utf-8" /> 
     </h:head> 
     <h:body> 
      <h:form id="testForm"> 

       <p:panel id="queryPanel" header="...test itext html-to-pdf conversion..." style="width:100%;"> 

        <table id='table1'> 
         <thead class="dt-thd"> 
          <tr id="table1-h-hdr-row"> 
           <th style="width: 120px" class="dt-hhdr-c " >Last name</th> 
           <th style="width: 120px" class="dt-hhdr-c " >First Name</th> 
           <th style="width: 120px" class="dt-hhdr-c " >Middle Name</th> 
           <th style="width: 180px" class="dt-hhdr-c " >Date Of Birth</th> 

          </tr> 
         </thead> 
         <tbody> 
          <tr class="dt-r-even" onclick="uiOnRowClick('table1', 14, this)"> 
           <td style="width: 120px" class="dt-c row-selected-left" ><a class="column-link " onfocus="uiOnRowClick('table1', 14, this.parentNode.parentNode)" onclick="storeFilters()" href="#">lastnameAAA</a></td> 
           <td style="width: 120px" class="dt-c row-selected" >firstnameAAA</td> 
           <td style="width: 120px" class="dt-c row-selected" >A</td> 
           <td style="width: 180px" class="dt-c row-selected" >11/27/1971</td> 
          </tr> 
          <tr class="dt-r-odd" onclick="uiOnRowClick('table1', 14, this)"> 
           <td style="width: 120px" class="dt-c " ><a class="column-link " onfocus="uiOnRowClick('table1', 14, this.parentNode.parentNode)" onclick="storeFilters()" href="#">lastnameBBB</a></td> 
           <td style="width: 120px" class="dt-c " >firstnameBBB</td> 
           <td style="width: 120px" class="dt-c " >B</td> 
           <td style="width: 180px" class="dt-c " >01/15/1951</td> 
          </tr> 
          <tr class="dt-r-even" onclick="uiOnRowClick('table1', 14, this)"> 
           <td style="width: 120px" class="dt-c " ><a class="column-link " onfocus="uiOnRowClick('table1', 14, this.parentNode.parentNode)" onclick="storeFilters()" href="#">lastnameCCC</a></td> 
           <td style="width: 120px" class="dt-c " >firstnameCCC</td> 
           <td style="width: 120px" class="dt-c " >C</td> 
           <td style="width: 180px" class="dt-c " >02/16/1962</td> 
          </tr> 
          <tr class="dt-r-odd" onclick="uiOnRowClick('table1', 14, this)"> 
           <td style="width: 120px" class="dt-c " ><a class="column-link " onfocus="uiOnRowClick('table1', 14, this.parentNode.parentNode)" onclick="storeFilters()" href="#">lastnameDDD</a></td> 
           <td style="width: 120px" class="dt-c " >firstnameDDD</td> 
           <td style="width: 120px" class="dt-c " >D</td> 
           <td style="width: 180px" class="dt-c " >03/17/1973</td> 
          </tr> 
          <tr class="dt-r-even" onclick="uiOnRowClick('table1', 14, this)"> 
           <td style="width: 120px" class="dt-c " ><a class="column-link " onfocus="uiOnRowClick('table1', 14, this.parentNode.parentNode)" onclick="storeFilters()" href="#">lastnameEEE</a></td> 
           <td style="width: 120px" class="dt-c " >firstnameEEE</td> 
           <td style="width: 120px" class="dt-c " >E</td> 
           <td style="width: 180px" class="dt-c " >04/18/1984</td> 
          </tr> 
          <tr class="dt-r-odd" onclick="uiOnRowClick('table1', 14, this)"> 
           <td style="width: 120px" class="dt-c " ><a class="column-link " onfocus="uiOnRowClick('table1', 14, this.parentNode.parentNode)" onclick="storeFilters()" href="#">lastnameFFF</a></td> 
           <td style="width: 120px" class="dt-c " >firstnameFFF</td> 
           <td style="width: 120px" class="dt-c " >F</td> 
           <td style="width: 180px" class="dt-c " >05/19/1995</td> 
          </tr> 
         </tbody> 
        </table> 

        <p:commandButton 
         id="printPdf" 
         value="Print" 
         action="#{testBean.createPDF2}" 
         ajax="false" 
         onclick="printPreview(this);this.form.target='_blank'"/> 

        <h:inputHidden id="htmlstring" value="no value"/> 

       </p:panel> 

      </h:form> 

      <h:outputStylesheet library="styles" name="itextweb.css"  /> 
      <h:outputScript  library="primefaces" name="/jquery/jquery.js" /> 
      <h:outputScript  library="primefaces" name="/jquery/plugins/ui/jquery-ui.custom.js" /> 
      <h:outputScript  library="primefaces" name="/jquery/plugins/inputmask/maskedinput.js" /> 
      <h:outputScript  library="js"   name="itextweb.js" /> 
     </h:body> 
    </f:view> 
</html> 

下面是使用的JavaScript ...

function uiOnRowClick(a, b, c) 
{ 
    alert("uiOnRowClick(a,b,c) function called...blah..."); 
} 

function storeFilters() 
{ 
    alert("storeFilters() function called...bleah..."); 
} 

function printPreview(e) 
{ 
    var t = document.getElementById("table1"); 
    var htmlstring = "<table id='table1-hdr' class='dt' style='width:2416px;position:absolute'>" + t.innerHTML + "</table>"; 
    document.getElementById('testForm:htmlstring').value = htmlstring; 
} 

這裏是CSS樣式表對於該示例...

.text1 
{ 
    background-color: transparent !important; 
    font-weight: bold; 
    font-size: 2em; 
    color: blue; 
    text-align:center; 
} 

.ui-inputfield { 
    background: white !important; 
    height: 10px !important; 
    vertical-align: middle; 
    display:inline-block; 
    white-space: nowrap; 
} 


.ui-button 
{ 
    margin-top: .5px !important; 
    vertical-align: middle !important; 
    display:inline-block !important; 
    white-space: nowrap !important; 
    text-align: center !important; 
} 

.ui-message-error 
{ 
    background: transparent !important; 
    border: none !important; 
    font-size: .9em !important; 
    font-weight: normal !important; 
    font-family: Arial, sans-serif !important; 
} 

.ui-message-error-icon { 
    display: none; 
} 

.ui-messages-error 
{ 
    background: transparent !important; 
    border: none !important; 
    font-size: .9em !important; 
    font-weight: normal !important; 
    font-family: Arial, sans-serif !important; 
} 

.ui-messages-error-icon { 
    display: none; 
} 

.ui-inputfield.ui-state-error 
{ 
    background: pink !important; 
} 

form * 
{ 
box-sizing: content-box !important; 
-moz-box-sizing: content-box !important; 
-ms-box-sizing: content-box !important; 
} 


.ui-widget, .ui-widget .ui-widget 
{ 
font-size: 90% !important; 
} 


.dt-thd 
{ 

} 

.table1-h-hdr-row 
{ 

} 

.dt-hhdr-c 
{ 
    color: blue; 
    background-color: lightgray; 
} 

.dt-r-odd 
{ 
    background-color: aliceblue; 
} 

.dt-r-even 
{ 
    background-color: lightskyblue; 
} 

.dt-c 
{ 
    font-size: 8px; 
    font-weight: normal; 
} 

下面是與本實施例中(其示出dependenies /版本/等)所使用的pom.xml的...

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>aaa.bbb.ccc</groupId> 
    <artifactId>itextweb-war</artifactId> 
    <packaging>war</packaging> 
    <version>1</version> 
    <name>itextweb-war</name> 
    <url>http://maven.apache.org</url> 

    <dependencies> 

     <dependency> 
      <groupId>javax.servlet</groupId> 
      <artifactId>servlet-api</artifactId> 
      <version>2.5</version> 
      <scope>provided</scope> 
     </dependency> 

     <dependency> 
      <groupId>javax.servlet</groupId> 
      <artifactId>jstl</artifactId> 
      <version>1.2</version> 
     </dependency> 

     <dependency> 
      <groupId>com.sun.faces</groupId> 
      <artifactId>jsf-api</artifactId> 
      <version>2.1.11</version> 
     </dependency> 

     <dependency> 
      <groupId>com.sun.faces</groupId> 
      <artifactId>jsf-impl</artifactId> 
      <version>2.1.11</version> 
     </dependency> 

     <dependency> 
      <groupId>javax.el</groupId> 
      <artifactId>el-api</artifactId> 
      <version>2.2</version> 
     </dependency> 
     <dependency> 
      <groupId>org.glassfish.web</groupId> 
      <artifactId>el-impl</artifactId> 
      <version>2.2</version> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-context</artifactId> 
      <version>3.1.1.RELEASE</version> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-webmvc</artifactId> 
      <version>3.1.1.RELEASE</version> 
     </dependency> 

     <dependency> 
      <groupId>commons-lang</groupId> 
      <artifactId>commons-lang</artifactId> 
      <version>2.6</version> 
     </dependency> 

     <dependency> 
      <groupId>commons-io</groupId> 
      <artifactId>commons-io</artifactId> 
      <version>2.4</version> 
     </dependency> 

     <dependency> 
      <groupId>org.primefaces</groupId> 
      <artifactId>primefaces</artifactId> 
      <version>3.4.2</version> 
     </dependency> 

     <dependency> 
      <groupId>org.primefaces.themes</groupId> 
      <artifactId>aristo</artifactId> 
      <version>1.0.1</version> 
     </dependency> 

     <dependency> 
      <groupId>com.itextpdf</groupId> 
      <artifactId>itextpdf</artifactId> 
      <version>5.3.4</version> 
     </dependency> 

     <dependency> 
      <groupId>com.itextpdf.tool</groupId> 
      <artifactId>xmlworker</artifactId> 
      <version>1.2.1</version> 
     </dependency> 

    </dependencies> 
    <build> 
     <plugins> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-compiler-plugin</artifactId> 
       <version>2.3.2</version> 
       <configuration> 
        <source>1.6</source> 
        <target>1.6</target> 
       </configuration> 
      </plugin> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-war-plugin</artifactId> 
       <version>2.3</version> 
      </plugin> 

     </plugins> 
     <finalName>${project.name}-${project.version}</finalName> 
    </build> 
</project> 
+0

此問題與JSF無關。也許你在你的web應用中使用JSF,但這個問題不在JSF範圍之內。 – 2013-02-09 02:45:39

+0

*我一直沒有能夠得到這個工作,並且不知道問題是什麼*。這是否意味着你沒有調試過你的代碼?你是否至少在'cssfiletest'或'null'中獲得了一個值(表示找不到該文件)? – 2013-02-09 02:46:57

+0

嗨Luiggi-你是否已經獲得了CssFile/CssResolver技巧來自己動手?如果是這樣,你能看到我提供的代碼snippits有任何明顯的問題嗎? Thx爲您提供幫助。 – sairn 2013-02-09 03:13:56

回答

3

從您的代碼開始創建一個項目,並進行測試,並且它非常適合從具有外部CSS的html文件創建PDF文件。

以下是公共存儲庫:https://github.com/valentin-nasta/itext-html-css-pdf-jsf-template

+0

嗨瓦倫丁 - 你也可以成功地將HTML表格本身轉換爲PDF(我在原文中添加了更多的代碼細節)?我實際上將表(及其內容)作爲字符串發佈到支持bean /控制器。我不想分析整個html頁面等。我嘗試調整您的解決方案來轉換上述表字符串,但是,我仍然收到相同的錯誤...〜文檔不包含任何頁面等。您認爲如何?順便說一句 - 非常感謝您參加我發佈的問題。 – sairn 2013-02-13 16:32:17

+2

我做了一些研究和接縫,xmlworker只支持一些CSS樣式。這裏有[支持的CSS樣式](http://demo.itextsupport.com/xmlworker/itextdoc/CSS-conformance-list.htm)。用一些基本的風格做了一些小的測試,比如'table {color}紅色; \t background-color:blue;並且它正在工作。 – 2013-02-15 12:40:23

+0

也發現了這個問題。在''.dt-hhdr-c'類的背景顏色上使用'lightgrey'來代替'lightgray',在我這邊這樣工作。快樂的編碼! – 2013-02-15 12:59:41

2

我認爲爲此目的(從XHTML生成PDF文件)更好,更強大(和更高級別的抽象)工具將是飛碟,又名。 xhmlrenderer。

它爲打印介質提供了完整的CSS2支持和一些CSS3屬性,您可以擴展它以渲染任何PDF(請參閱ReplacementElementFactory API)。

我用它來渲染動態PDF報告(帶有freemarker)和自定義標籤一樣。非常簡單的工具,易於理解。

參見:http://code.google.com/p/flying-saucer/

用戶指南可以在這裏找到:http://flyingsaucerproject.github.com/flyingsaucer/r8/guide/users-guide-R8.html

+0

謝謝,Persics。不幸的是,我不允許使用Flying Saucer軟件。 – sairn 2013-02-18 23:59:02

0

對於cssResolver你需要如下圖所示,以指定的.css的absoulte路徑。

​​
2

nope飛碟超出生命不再支持了。我們遇到了很多麻煩。爲私人使用它的好,但不是在商業案件。