JasperReport生成pdf檔案 Java開發pdf檔案 pdf檔案生成及下載

Java製作開發pdf檔案可以使用JasperReport框架。最近專案中需要後端生成pdf檔案,為了高效快捷開發,選用了jasperreport框架。期間踩了不少坑,以此博文做些記錄總結,希望對你也有一些幫助。

不管使用何種報表製作框架,一般都要有三個大的步驟:

設計模板

填充引數

渲染匯出

使用jasperreport當然也會遵循上面的流程

一、設計pdf報表模板

jasperreport設計報表模板的工具是Jaspersoft Studio(到官網下載即可),如下圖

JasperReport生成pdf檔案 Java開發pdf檔案 pdf檔案生成及下載

Jasper報表設計工具

進入工具製作自己需要的報表模板即可,製作pdf檔案模板時需要對studio工具進行一些簡單的設定(

詳見文章末尾說明

),否則預覽的時候中文字型將無法顯示。設計後的模板如下圖示:

JasperReport生成pdf檔案 Java開發pdf檔案 pdf檔案生成及下載

報表模板設計

二、填充pdf模板引數

模板製作完成後,在工具中編譯生成二進位制jasper檔案就可以在專案中使用了(不編譯也行,編譯後代碼執行時就無需在編譯,會提高執行速度)。將jasper檔案放到專案resources目錄下,如下圖:

JasperReport生成pdf檔案 Java開發pdf檔案 pdf檔案生成及下載

專案中使用jasper

上圖中同時也給出了jasperreport生成pdf檔案時需要用到的字型設定(有漢字時必須設定中文字型),宣告字型有三部分:

1. jasperreports_extension.properties配置檔案

配置檔案內容如下:

net。sf。jasperreports。extension。registry。factory。fonts=net。sf。jasperreports。engine。fonts。SimpleFontExtensionsRegistryFactorynet。sf。jasperreports。extension。simple。font。families。default=fonts/fonts。xml

jasper框架會透過此配置檔案去載入指定的字型xml檔案

2. 字型族xml宣告檔案

字型xml檔案內容如下:

<?xml version=“1。0” encoding=“UTF-8”?> fonts/STSong。TTF fonts/STSong。TTF fonts/STSong。TTF fonts/STSong。TTF fonts/STSong。TTF fonts/STSong。TTF fonts/STSong。TTF Identity-H true

注意:

fontFamily name=“

my_songT

” name的值需要和你設計模板時用到的字型名字一樣

3. ttf字型包

ttf字型包是一個字型庫,我專案中用的是STSong。TTF,當時為了下載字型包也是一頓好找(很多都是噁心人的誘導下載),不過還是有好心人分享到了GitHub上,直接到上面搜尋即可。

至此生成pdf的準備工作已經ok。然後就是根據你自己的業務組裝模板需要的資料,填充模板引數即可。參考如下:

public void exportReportOrder(Integer reportId, HttpServletResponse servletResponse) { //查詢自己需要的業務資料 ReportOrderDetailVO detailVO = this。getReportOrderDetail(reportId); OutputStream outputStream; try { outputStream = servletResponse。getOutputStream(); String fileName = reportOrderConverter。getPdfFileName(detailVO); //設定http的檔案型別及編碼方式 servletResponse。setContentType(“application/pdf;charset=utf-8”); //設定下載的檔名稱 名稱含有中文的話需要用URLEncoder進行編碼 servletResponse。setHeader(“content-disposition”, “attachment;filename=” + URLEncoder。encode(fileName, “utf-8”)); Map reportTypeToNameMap = reportTypeEnumService。getCodeToNameMap(); ExportFraudReportOrderResponse response = reportOrderConverter。assembleFraudReportOrder(detailVO, reportTypeToNameMap); //組裝模板中需要的引數 用於填充模板中透過$P{xxx}宣告的引數 Map params = reportOrderConverter。assembleReportParams(response); List imageList = reportOrderConverter。getImageResources(detailVO); //設定JasperReport的資料來源 我用的是Json型別的資料來源(資料來源中的資料用於填充模板中detail區域的透過$F{XXX}指定的引數) JsonDataSource jsonDataSource = new JsonDataSource(new ByteArrayInputStream(JSON。toJSONString(imageList)。getBytes(StandardCharsets。UTF_8))); boolean hasImage = reportOrderConverter。hasImage(detailVO); if (hasImage) { fileGenerateService。generates(EnumFileMeta。PDF_4_FRAUD_REPORT, outputStream, params, jsonDataSource); } else { fileGenerateService。generates(EnumFileMeta。PDF_4_FRAUD_REPORT_WITHOUT_IMAGE, outputStream, params, jsonDataSource); } } catch (IOException io) { log。error(“獲取http輸出流失敗”, io); throw new ServiceResponseException(“獲取http輸出流失敗”); } catch (Exception e) { log。error(“生成報告單失敗”, e); throw new ServiceResponseException(“生成報告單失敗”); } }

三、渲染匯出pdf檔案

前面兩個步驟完成之後,最後一步就是使用JasperReport框架提供的API生成匯出pdf檔案就行了,API使用很簡單,如下:

/** * * @param fileMeta 自己封裝的列舉 可以忽略 * @param outputStream 報表要生成的目的地 專案需求是讓使用者從瀏覽器直接下載的 所以此處用的是HttpServletResponse的輸出流 * @param params 填充報表模板中$P{xxx}的引數 * @param dataSource 填充報表模板中$F{xxx}的資料來源 */ public void exportFile(EnumFileMeta fileMeta, OutputStream outputStream, Map params, JRDataSource dataSource) { try { //載入專案中resources目錄下的報表模板 注意:透過Class載入資源 資源地址必須是絕對路徑 InputStream reportTemplate = this。getClass()。getResourceAsStream(“/template/fraud_report。jasper”); //將引數和資料來源填充到報表模板中 JasperPrint jasperPrint = JasperFillManager。fillReport(reportTemplate, params, dataSource); //框架匯出pdf的API 匯出檔案到輸出流 JasperExportManager。exportReportToPdfStream(jasperPrint, outputStream); return; } catch (Exception e) { log。error(“pdf檔案匯出異常”, e); } finally { try { outputStream。flush(); outputStream。close(); } catch (IOException e) { log。error(“pdf檔案匯出 沖刷/關閉輸出流異常 ”, e); } } throw new ServiceResponseException(“pdf檔案匯出異常”); }

至此,透過JasperReport框架生成pdf檔案就全部完成了。本例成品如下圖:

JasperReport生成pdf檔案 Java開發pdf檔案 pdf檔案生成及下載

最終生成的pdf檔案效果

踩坑小計

itext包的版本要選對,

建議使用2.1.7版本

,否則會報錯(jasperReport 的依賴只和 itext的 2。1。7 版本相容,不相容其他版本)

net。sf。jasperreports jasperreports 6。11。0 itext com。lowagie commons-collections4 org。apache。commons com。lowagie itext 2。1。7

如果在maven pom檔案中添加了對resources資源進行了過濾,那麼必須宣告

對jasper檔案和ttf檔案

不過濾

,否則會報錯(如下):

如不宣告jasper,那麼在載入jasper模板檔案時候會報

invalid stream header

: EFBFBDEF 的錯誤 ;

如不宣告ttf,那麼在匯出pdf檔案的時候會報字型找不到的錯誤:net。sf。jasperreports。engine。util。JRFontNotFoundException: Font “my_songT” is not available to the JVM。 See the Javadoc for more details。

原因:

如果專案中有二進位制或其他敏感檔案,請不要使用maven對其進行filter,否則會破壞原始檔!!!

pom檔案宣告如下:

src/main/resources **。* **/**。* true **/*。jasper **/*。TTF src/main/resources **/*。jasper false src/main/resources **/*。TTF false

JasperStudio工具配置pdf字型

1。新增字型,選擇自己電腦本地的中文TTF字型包,起一個易用的名字,如下圖

JasperReport生成pdf檔案 Java開發pdf檔案 pdf檔案生成及下載

設定字型

2。設定pdf匯出器,如下圖

JasperReport生成pdf檔案 Java開發pdf檔案 pdf檔案生成及下載

設定匯出器

3。設定模板的時候選擇剛才設定的字型,然後就可以透過studio工具快速預覽pdf報表了(注:其他模板無需專門配置字型),如果不使用配置的中文字型,那麼預覽的時候漢字是無法顯示的,如下圖:

JasperReport生成pdf檔案 Java開發pdf檔案 pdf檔案生成及下載

應用字型

本文結束,希望對你有所啟發!