CrystalReports水晶报表开发中遇到的问题
一、模板中用到的字體
1.水晶報表官方文檔直接說明,如果需要導出PDF,則只支持ttf字體
2.在使用中發現,并非所有ttf字體都能導出PDF,如阿里巴巴普惠體。
由于對字體文件不熟悉,目前只知道在讀取字體文件時,會查詢一堆Table。
其中的ControlValueTable無法獲取fontTableName,在此過程中拋出空指針異常,導致無法導出PDF。
3.初次讀取報表模板文件時,優先從java運行時環境依賴下查詢字體/jre/lib/font,次之是系統安裝的字體。
讀取字體到結構Map<String,Font>中,其中String為字體名稱。
在讀取某些中文字體時,key為null,發現此現象的字體是從某個字體站下載的漢儀字體包。
4.除了以上字體外,目前使用的大部分ttf中文字體都可以正常導出PDF,如微軟雅黑、楷體、宋體、文泉驛正黑等,但是會出現第二條問題,如下所示。
二、chrome瀏覽器無法顯示個別中字
1.直接從瀏覽器打印也會打印空白字
2.不同字體不顯示的字不同,尚未發現能完美顯示所有字的中文字體
3.Firefox和IE正常顯示所有字
4.從chrome保存到本地后,使用其他PDF編輯器(如acrobat)打開,所有字正常顯示
5.從chrome中的PDF空白字處復制不顯示的字符,到本地文本編輯器(如NotePad++)可以正常顯示該字
6.使用水晶報表編輯工具SAP Crystal Reports無論是預覽還是導出PDF均可以正常顯示所有字
7.當模板中配置了【思源黑體.otf】且系統和jre/lib/font下均不存在阿里巴巴普惠體時,
輸出PDF到chrome瀏覽器可以顯示所有字,但是點擊下載或打印會導致瀏覽器崩潰。
偶爾可以下載成功,下載得到的PDF使用本地其他PDF編輯器打開會導致編輯器崩潰。
解決方案:
1.升級chrome至79.0.3945.88或以上,基本上可以確定是chrome對各個版本的pdf兼容性有自己的想法導致的問題。
2.先把水晶報表生成的PDF轉成圖片,再將圖片嵌入新的PDF文檔,最終將新的PDF文檔輸出至瀏覽器。
實例如下所示:
1.pdfbox
引入第三方庫。
<!-- https://mvnrepository.com/artifact/org.apache.pdfbox/pdfbox --> <dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.18</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.pdfbox/pdfbox-tools --> <dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox-tools</artifactId><version>2.0.18</version> </dependency>2.PDF轉圖片
非最佳實現,僅供參考。
PDDocument originDocument = PDDocument.load(reportStream); PDFRenderer originRender = new PDFRenderer(originDocument); String rootPath = new File(".").getAbsolutePath() + "/tmp_report_"; int pageSize = originDocument.getNumberOfPages(); try (PDDocument targetDocument = new PDDocument()) {for (int pageNum = 0; pageNum < pageSize; ++pageNum) {// 將一頁轉為圖片String filePath = rootPath + pageNum + ".png";BufferedImage bufferedImage = originRender.renderImageWithDPI(pageNum, REPORT_DPI, ImageType.GRAY);// int REPORT_DPI = 300ImageIOUtil.writeImage(bufferedImage, filePath, REPORT_DPI);// 載入圖片并轉為PDF圖像對象PDImageXObject pdImage = PDImageXObject.createFromFile(filePath, targetDocument);PDPage page = new PDPage();// 創建新的PDF文檔并添加圖片targetDocument.addPage(page);PDPageContentStream content = new PDPageContentStream(targetDocument, page);content.drawImage(pdImage, 0, 0, ?page.getMediaBox().getWidth(), page.getMediaBox().getHeight());content.close();Files.deleteIfExists(Paths.get(filePath));}// 將新的PDF文檔輸出到響應流targetDocument.save(response.getOutputStream()); } catch (Exception e) {LoggerUtil.getLogger().error("PDF渲染失敗", e); }值得注意是:dpi、圖片格式、渲染類型。
-
dpi設為300,保證清晰度
-
圖片格式為png
-
渲染類型為ImageType.GRAY
經過測試,后兩個值若為jpg+ImageType.RGB等其他組合,則經過圖片轉換的PDF大小會增長很多(數倍之多)。
故建議設為png+ImageType.GRAY的組合,或有測試過更好的方式歡迎指正。
除此之外,將生成的圖片嵌入新的PDF文檔后,存在圖片比例畸變的問題。
content.drawImage(pdImage, 0, 0, ?page.getMediaBox().getWidth(), page.getMediaBox().getHeight());畸變比較小,由于測試PDF內容存在圓形圖片水印才被發現,可根據實際顯示情況進行微調。
content.drawImage(pdImage, REPORT_X_OFFSET, 0,page.getMediaBox().getWidth() - REPORT_WIDTH_OFFSET, page.getMediaBox().getHeight());畸變調整前:
畸變調整后:
三、Java bean作為數據源
1.修改CRConfig.xml配置,在SAP Crystal Reports2016中,需要修改:
-
JavaDir32
-
JavaDir64
-
JavaBeansClassPath
2.通過閱讀官方說明文檔,Bean文件需要編譯為.class文件或打包為.jar文件。
.class需配置JavaBeansClassPath為路徑,.jar需配置JavaBeansClassPath為路徑+xxx.jar。
3.bean文件中需要包含返回類型為java.sql.ResultSet的方法,不可以返回null,不可以是不能正常運行的SQL,否則在報表編輯器中連接時均無法連接。一個示例如下:
public ResultSet getDoorBean() throws ReportSDKException {List<DoorBean> doorItems = new ArrayList<>();POJOResultSetHelper helper = new POJOResultSetHelper(DoorBean.class);return helper.createResultSet(doorItems); }其中,getDoorBean會成為編輯器中數據源連接的表名,也是讀取并注入數據源時需要寫入的表名。
4.編譯為.class文件并且正確配置JavaBeansClassPath后,打開SAP Crystal Reports2016,選擇Java bean connectivity,在下拉框中應當出現javaservertype=javabeans javabeanname=的字樣。
并非直接出現bean的名稱,只有連接成功后下拉框中才會出現bean名稱列表。
成功連接后,bean字段與jdbc方式獲取的字段一樣,可以拖拽到模板中。
5.如果bean字段修改,可以通過【驗證數據庫】操作進行字段更新,避免重新連接數據源導致重新配置字段,驗證的字段通過名稱進行比對映射。
四、圖片
1.暫時未發現使用相對路徑讀取到圖片的方法
2.使用絕對路徑可以讀取圖片
3.使用URL可以讀取圖片,但是官方論壇的答復是:不支持https
4.可以通過公式字段獲取模板的絕對路徑,再通過模板與圖片的相對位置關系獲得圖片路徑,如下所示:
Left(Filename,length(filename) - Length(Mid (Filename ,InstrRev (Filename,"\") + 1) ))但是不解決問題,因為使用tomcat運行后端時,讀取一次模板文件,就默認在tomcat/temp下生成臨時模板數據。
此時獲取到的模板路徑是tomcat/temp,而非項目路徑。
5.關于模板文件
在本地運行中發現,如果刪除tomcat路徑下的temp文件夾,臨時文件被生成到idea intellij的安裝路徑下的temp文件夾中。
論壇的答復是,只要ReportClientDocument流被close,臨時文件就會被刪除,實際上并沒有。
6.透明背景
Crystal Reports converts images to .bmp which unfortunately does not support transparency for images.官方論壇關于透明背景顯示黑色的答復如上,不支持透明,但是也未給出比如設置背景色為白色或黑色的解決方案。
總結
以上是生活随笔為你收集整理的CrystalReports水晶报表开发中遇到的问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 管理学基础理论
- 下一篇: Visual Studio 水晶报表Cr