2016-08-22 41 views
4

我嘗試在Jasper Reports中格式化Date,它適用於Windows,但不適用於Linux。在Linux中,結果文本被截斷。爲什麼使用Linux在PDF中截斷文本?

代碼:

JRXML:

<parameter name="timestamp" class="java.util.Date"/> 
[...] 
<textField> 
    <reportElement x="0" y="0" width="50" height="16" uuid="0007846a-26f1-457a-a198-67a2f7c8417c"> 
     <property name="local_mesure_unitwidth" value="pixel"/> 
     <property name="com.jaspersoft.studio.unit.width" value="px"/> 
     <property name="local_mesure_unitx" value="pixel"/> 
     <property name="com.jaspersoft.studio.unit.x" value="px"/> 
     <property name="local_mesure_unity" value="pixel"/> 
     <property name="com.jaspersoft.studio.unit.y" value="px"/> 
     <property name="local_mesure_unitheight" value="pixel"/> 
     <property name="com.jaspersoft.studio.unit.height" value="px"/> 
    </reportElement> 
    <box padding="2"/> 
    <textElement textAlignment="Left" verticalAlignment="Top"> 
     <font size="8" pdfFontName="Helvetica" pdfEncoding="Cp1250" isPdfEmbedded="true"/> 
    </textElement> 
    <textFieldExpression><![CDATA[DATEFORMAT($P{timestamp},"dd.MM HH:mm")]]></textFieldExpression> 
</textField> 

Maven依賴:

<dependency> 
    <groupId>net.sf.jasperreports</groupId> 
    <artifactId>jasperreports</artifactId> 
    <version>5.6.0</version> 
</dependency> 
<dependency> 
    <groupId>net.sf.jasperreports</groupId> 
    <artifactId>jasperreports-functions</artifactId> 
    <version>5.6.0</version> 
</dependency> 

的Java:

private byte[] createPdf() { 

    try { 
     InputStream is = getClass().getResourceAsStream("MyReport.jasper"); 
     JasperReport jasperReport = (JasperReport) JRLoader.loadObject(is); 
     Map<String, Object> parameters = new HashMap<String, Object>(); 
     parameters.put("timestamp", new Date()); 
     JRDataSource jrDataSource = new JRBeanCollectionDataSource(new Vector(), false); 
     JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, jrDataSource); 
     byte[] pdf = JasperExportManager.exportReportToPdf(jasperPrint); 
     return pdf; 
    } catch (JRException e) { 
     throw new RuntimeException("Could not create PDF.", e); 
    } 
} 

結果:

結果與Windows:

Windows

結果使用Linux:

Linux

PDF屬性:

兩個生成的PDF文件在Acrobat Reader軟件相同的字體屬性的Windows:

PDF properties

正如你所看到的,字體沒有嵌入。 (如果我添加依賴關係jasperreports-fonts並刪除屬性pdfFontName,pdfEncodingisPdfEmbedded),第二個字體「Helvetica」消失。

研究:

我讀:

和解決方案似乎是嵌入字體,但它不工作。

我使用字體「黑體」,這是默認的字體之一,這就是原因,看Wikipedia

這些字體,或者合適的替代字體用相同的指標,必須始終在所有PDF可讀者因此不需要嵌入到PDF

https://stackoverflow.com/a/27345103/5277820

如果您在iText的使用這些字體,iText的w ^虐待忽略嵌入參數,因爲假定Adobe Reader和其他查看器可以正確呈現這些字體是安全的。

問:

爲什麼有Windows和Linux相同的字體不同的寬度?或者爲什麼文本截斷和/或換行不同?

+1

是的,你應該總是嵌入字體,以避免問題。請參閱http://stackoverflow.com/a/26632606/5292302中的4錯誤(答案來自itext創始人),不是最好的例子,但給出了編碼實踐的概念,總是提供並嵌入字體 –

回答

3

要正確計算字體指標,字體需要可用於Java虛擬機。

看到這個歷史問題:Font is not available to the JVM with Jasper Reports,這顯示出各種解決舊的錯誤推出

然而,隨着碧玉報告正確的解決方案是使用字體的擴展

如果你使用分佈式jasperreports-font.jar它包含這些字體:

幻覺記憶三世
幻覺記憶襯線
幻覺記憶國界單

您需要使用其中的一個在字體名稱例如fontName="DejaVu Sans",也沒有自動映射到其他字體,罐子實際只包含這些.ttf並沒有其他(打開罐子,驗證不同版本的碧玉報告) 。

因此,只有安裝在電腦上或包含在font-extension中的字體纔可用於JVM。

如果您需要其他字體,最好的解決方案是生成自己的字體擴展名,包括有效的.ttf字體,這可以在IDE中完成。

0

永遠不要假設客戶端系統上有特定的字體 - 市場上只有幾種桌面操作系統的日子已經過去,只有少數西方語言可用,並且有着名的字體列表幾十年來一直穩定。 (使用新的虛榮字體),Unicode.org發佈了新的規範(這需要檢修現有的字體),因此不同系統中出現的實際字體差別很大。

OSX和Windows在舊的「固定字體列表」模式下仍然有些功能,但新進入者不會。

對於PDF,這意味着您必須在文檔中嵌入字體。 對於網絡來說,這意味着靈活的網站設計不依賴於確切的像素字母尺寸。

試圖使用像Helvetica或Arial這樣舊的遺留字體是一種病​​態的情況:客戶端根本不會安裝它,並將它別名爲具有不同字形度量標準的東西,或者它會有一個古老的版本,那是因爲ASCII不再支持所添加的所有代碼點,並且將無法呈現現代國際文本。 Arial由於長時間佔據主導地位而工作的可能性更大,但這種情況迅速惡化。