2013年2月17日 星期日

Test XDocReport v1.0.0

XDocReport API v1.0.0 己於 2012/12/02 Release 並提供下載,之前有對 1.0.0 SNAPHOT 版本做初步測試,現在則針對 v1.0.0 測試看之前遇到的問題是否有獲得解決。
問題的描述可參考 MS Word Converter to Word/PDF by XDocReport API Getting StartedHow can XDocReport (to PDF) supply the Chinese character


準備執行環境

測試時會用到的環境,因字型是直接使用 OS 的,因此也列出版本提供參考
  • Windows 7
  • JDK (Java Development Kit) version 1.6+
  • Apache Maven 2.2.1+
  • XDocReport 1.0.0

XWPFConverterPDFViaIText - XWPFDocument 2 PDF 有提到要下載的 Sample 及 maven dependency ,下載 docx.converters-1.0.0-sample.zip (Samples with Java DOCX 2 PDF/XHTML converter based on Apache POI+iText) 。


Build & Test DOCX 2 PDF/XHTML converter based on Apache POI+iText


  1. 比照之前的方式,將下載的 zip file 解壓縮到 maven 的目錄結構,新增 pom.xmlline-43 ~ 60 version 都設定為 1.0.0line-61 是這次測試主要會使用到的 librarys,line-67 則是使用 org.apache.poi.xwpf.converter.itext.PDFViaITextOptions 會參照的。
  2. <?xml version="1.0" encoding="UTF-8"?>
    <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/xsd/maven-4.0.0.xsd">
       <modelVersion>4.0.0</modelVersion>
       <groupId>docxConverters</groupId>
       <artifactId>docxConverters</artifactId>
       <version>1.0-SNAPSHOT</version>
       <name>docxConverters</name>
       <url>http://maven.apache.org</url>
       <build>
          <plugins>
             <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                   <source>1.6</source>
                   <target>1.6</target>
                   <encoding>UTF-8</encoding>
                </configuration>
             </plugin>
             <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                   <encoding>UTF-8</encoding>
                </configuration>
             </plugin>
             <!--            -->
             <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                   <skipTests>true</skipTests>
                </configuration>
             </plugin>
          </plugins>
          <resources>
             <resource>
                <directory>src/main/resources</directory>
             </resource>
          </resources>
       </build>
       <dependencies>
          <!--     use MS Word docx       -->
          <dependency>
             <groupId>fr.opensagres.xdocreport</groupId>
             <artifactId>fr.opensagres.xdocreport.document.docx</artifactId>
             <version>1.0.0</version>
          </dependency>
          <!--     use Velocity       -->
          <dependency>
             <groupId>fr.opensagres.xdocreport</groupId>
             <artifactId>fr.opensagres.xdocreport.template.velocity</artifactId>
             <version>1.0.0</version>
          </dependency>
          <!--     convert docx 2 PDF/XHTML       -->
          <dependency>
             <groupId>fr.opensagres.xdocreport</groupId>
             <artifactId>fr.opensagres.xdocreport.converter.docx.xwpf</artifactId>
             <version>1.0.0</version>
          </dependency>
          <!--     XWPFDocument 2 PDF       -->
          <dependency>
             <groupId>fr.opensagres.xdocreport</groupId>
             <artifactId>org.apache.poi.xwpf.converter.pdf</artifactId>
             <version>1.0.0</version>
          </dependency>
          <!--     convert POI XWPF       -->
          <dependency>
             <groupId>fr.opensagres.xdocreport</groupId>
             <artifactId>org.apache.poi.xwpf.converter</artifactId>
             <version>0.9.8</version>
          </dependency>
       </dependencies>
    </project>
    


  3. 新增 src\main\java\fr\opensagres\xdocreport\samples\docx\converters\pdf\ConvertDocxToPDF.java,步驟 1、2、3、5 跟之前的 Sample 方式一致。
    • 第4步驟 line-74 主要目的有二個設定字型來源及將 PdfOptions 轉換為 Options 。
    • 字型的設定有二種方式,a.字型所在的目錄(line-77),b.設定字型檔(line-78),但預設是會指向系統的字型路徑(c:/Windows/Fonts)因此不新增設定。
    • 另外執行 XDocReportRegistry.convert()(line-85) 時只接受 Options 因此須要將 PdfOptions 轉換為 Options(line-82),並且需要設定 fontEncodingBaseFont.IDENTITY_H
    • 官網的說明 XWPFConverterPDFViaIText - XWPFDocument 2 PDF 這部份一樣建議設定為 fontEncodingwindows-1250 但中文無法轉換成功。
    • line-81fr.opensagres.xdocreport.converter javadoc 建議的做法一樣中文無法轉換成功,而 ConverterTypeVia.XWPF 在 v1.0.0 之前可以設定為 ConverterTypeVia.ITEXT 但 v1.0.0 已經取消了改設定為 ConverterTypeVia.XWPF
  4. package fr.opensagres.xdocreport.samples.docx.converters.pdf;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.Date;
    import java.awt.Color;
    
    import org.apache.poi.xwpf.converter.pdf.PdfConverter;
    import org.apache.poi.xwpf.converter.pdf.PdfOptions;
    import org.apache.poi.xwpf.usermodel.XWPFDocument;
    
    import com.lowagie.text.Font;
    import com.lowagie.text.pdf.BaseFont;
    import com.lowagie.text.FontFactory;
    //import org.apache.poi.xwpf.converter.itext.PDFViaITextOptions;
    import fr.opensagres.xdocreport.core.XDocReportException;
    import fr.opensagres.xdocreport.document.IXDocReport;
    import fr.opensagres.xdocreport.document.registry.XDocReportRegistry;
    import fr.opensagres.xdocreport.template.IContext;
    import fr.opensagres.xdocreport.template.TemplateEngineKind;
    import fr.opensagres.xdocreport.converter.ConverterTypeTo;
    import fr.opensagres.xdocreport.converter.ConverterTypeVia;
    import fr.opensagres.xdocreport.converter.Options;
    import org.apache.poi.xwpf.converter.pdf.ITextFontRegistry;
    
    public class ConvertDocxToPDF
    {
    
        public static void main( String[] args )
        {
            long startTime = System.currentTimeMillis();
    
            try
            {
            // 1) Load Docx file by filling Velocity template engine and cache
                // it to the registry
                InputStream in = ConvertDocxLettreRelanceToPDF.class
                .getResourceAsStream("TestChineseFontType.docx");
                IXDocReport report = XDocReportRegistry.getRegistry().loadReport(
                in, TemplateEngineKind.Velocity);
    
            // 2) Create context Java model
                IContext context = report.createContext();
    
                Calendar rightNow = Calendar.getInstance();
                int year = rightNow.get(Calendar.YEAR);
                int month = rightNow.get(Calendar.MONTH)+1;
                int day = rightNow.get(Calendar.DAY_OF_MONTH);
    
                //  直接格式化輸出現在時間的方法
                SimpleDateFormat sdFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
                Date current = new Date();
                String fCurrent = sdFormat.format(current);
                //System.out.println(fCurrent);
    
                context.put("name", "王小明");
                context.put("year", year);
                context.put("month", month);
                context.put("day", day);
                context.put("currentDate", fCurrent);
    
    
            // 3) Set OutputStream
                File outFile = new File( "target/TestChineseFontType.pdf" );
                outFile.getParentFile().mkdirs();
                OutputStream out = new FileOutputStream( outFile );
    
    
            // 4) PdfOptions Converter to fr.opensagres.xdocreport.converter.Options
    
                //Font Register
                //int fontRegisterNum = FontFactory.registerDirectory("c:/Windows/Fonts");
                //FontFactory.register("c:/Windows/Fonts/arialuni.ttf");
    
                //Unicode encoding with horizontal writing
                //Options options = Options.getTo(ConverterTypeTo.PDF).via(ConverterTypeVia.XWPF).subOptions(PDFViaITextOptions.create().fontEncoding(BaseFont.IDENTITY_H));
                Options options = Options.getTo(ConverterTypeTo.PDF).via(ConverterTypeVia.XWPF).subOptions(PdfOptions.create().fontEncoding(BaseFont.IDENTITY_H));
    
            // 5) Generate report by merging Java model with the Docx
                report.convert(context, options, out);
            }
            catch ( Throwable e )
            {
                e.printStackTrace();
            }
    
            System.out.println( "Generate DocxLettreRelance.pdf with " + ( System.currentTimeMillis() - startTime )
                + " ms." );
        }
    }
    


  5. 執行後可從檔案的比對看到結果,左邊為 Word 右邊為 PDF ,開頭二個 新細明體(本文/標題) 無法轉換,經測試的結果從c:/Windows/Fonts 讀取字型時有些字型名稱就是亂碼,造成無法判斷字型也就無法輸出(3百多個字型裡大概有10個左右的字型名稱無法讀取),至於套印的文字輸出也正常。



測試申請書的套印

  1. 將有套印需求的申請書依前一節的方式進行測試,結果三個 word 檔都於執行時出現錯誤,將 ConvertDocxToPDF.java 的步驟4進行如下改寫,再測試三個 word 檔則一個成功轉換,二個則將可能造成無法執行的部份刪除後再執行也可成功轉換,但刪除是整頁的刪除,沒有做細部追縱。
  2. ....
    
    
            // 4) PdfOptions Converter to fr.opensagres.xdocreport.converter.Options
    
                PdfOptions pdfOptions = PdfOptions.create();
                pdfOptions.fontProvider( new ITextFontRegistry()
                {
                    public Font getFont( String familyName, String encoding, float size, int style, Color color )
                    {
                        try
                        {
                            BaseFont bfChinese =
                                BaseFont.createFont( "c:/Windows/Fonts/arialuni.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED );
                            Font fontChinese = new Font( bfChinese, size, style, color );
                            if ( familyName != null )
                                fontChinese.setFamily( familyName );
                            return fontChinese;
                        }
                        catch ( Throwable e )
                        {
                            e.printStackTrace();
                            // An error occurs, use the default font provider.
                            return ITextFontRegistry.getRegistry().getFont( familyName, encoding, size, style, color );
                        }
                    }
    
                } );
    
                Options options = Options.getTo(ConverterTypeTo.PDF).via(ConverterTypeVia.XWPF).subOptions(pdfOptions);
    
    ....
    


  3. 執行成功的檔案做如下的比對,紅框出現空白行,整份文件出現7次這種情況,而直式的合併儲存格也可正常顯示;左右排列的條文則還滿正常的,字型的部份當然只顯示一種字型。



相關問題說明

針對 XDocReport API v1.0.0 將截至目前的測試做如下整理(非全面性的),Word to Word 則不再贅述:

  1. 直式儲存格已可正常顯示,但會有出現多餘空白行的問題。
  2. 中文部份某些字型還是無法顯示。
  3. 上述二點再加上整體測試後,除了確定中文某些字型無法顯示外,如套印後的PDF出現轉換錯誤或格式與來源檔(word)不符,可透過修改來源檔來調整,來源檔如避免線條重疊及隱藏的空白,則可增加格式的正確性。


相關設定可參考:
XDocReport API
Issue 81: how can xdocreport supply the Chinese character.
XWPFDocument 2 PDF

沒有留言:

張貼留言