1。簡介
在實踐中,我們看到以某種格式統計和匯出資料的請求是很常見的。例如,我們收到匯出客戶統計報告、銷售發票、採購發票等的請求,這需要人們(尤其是程式設計師)建立軟體,您可以根據每個具體情況和要求靈活建立匯出資料的範本。你可能立刻想到的解決方案是使用Word、Excel…,但這個解決方案不適合大量不斷變化、短時間內發展的數據,同時還需要支付軟體費用和數據處理時間不是最佳的。
目前有一個相當流行的解決方案——許多程式設計師都喜歡使用的JasperReports庫。
特別是,這個庫是開源的,並且有免費版本。您可以存取其原始程式碼:https://github.com/TIBCOSoftware/jasperreports
2。使用說明
關於如何使用這個庫網上有很多說明,這裡就不詳細寫了
如果您使用 Eclipse,JasperReports 有一個額外的外掛程式可以幫助您建立報告範本。
在這篇文章中,我將指導您在IntelliJ IDEA上使用它,庫管理器是maven。
首先,您需要一個範本來填寫資料(如訂單、發票等)。為此,請下載並安裝 Jaspersoft Studio 軟體(最新的社群版本連結目前為 https://community.jaspersoft.com/files/file/19-jaspersoft®-studio-community-edition /?do=getNewComment)。
安裝開啟後,軟體會有以下介面:
要建立新模板,請前往檔案 ->新->賈斯珀報告。在「全部」部分中,選擇「空白 A4」(或您喜歡的其他範本:>)。
按一下“下一步”,指定檔案的儲存位置。點選下一步->下一步->結束。出現的新介面是模板介面,您可以根據自己的模板自由設計。
右邊是函式庫支援的物件。
假設我必須建立一個帶有標題和商品名稱的簡單購買發票表格。我將“靜態文字”物件拖放到範本中,並輸入名稱“採購發票”(您可以在螢幕右上角自行調整格式)。
接下來,我再拖曳 2 個類似的對象,但將物品類別設定在「書籍」和「鋼筆」下方。
接下來我必須加入這 2 件商品的價格。這個值是動態的,所以我必須在這裡包含一個變數(這也是這個庫的一個非常有趣和靈活的功能)。在大綱部分、參數部分中,右鍵點選並選擇「建立參數」。然後我在右角視窗修改了這個變數的值,變數名為book,資料型別為實數。
然後我將其拖曳到「Book」標籤旁。與變數“筆”和總量相同。這裡你可以分配的總金額等於變數「book」和「pen」的總和。
完成模板後,它會是這樣的
您切換到來源選項卡,這是系統將處理的資料。基本上,Jasper Report 將以類似於 XML 的文件格式接收輸入數據,但標籤名稱將由庫預先定義。例如,整個檔案的超類別的開始和結束標記必須是「jasperReport」標記。以下是一些必須注意的模板符號:
完成後,您可以開始將此文件複製到您的專案中以填充資料並進行處理。
然後繼續導入以下庫:
<dependency> <groupId>net.sf.jasperreports</groupId> <artifactId>jasperreports</artifactId> <version>6.21.0</version> </dependency> <dependency> <groupId>net.sf.jasperreports</groupId> <artifactId>jasperreports-fonts</artifactId> <version>6.21.0</version> </dependency>
繼續編寫程式碼匯入檔案並填入資料。
final String outputFilename = "report.pdf"; Files.deleteIfExists(new File(outputFilename).toPath()); InputStream inputStream = Main.class.getResourceAsStream("/report.jrxml"); Map<String, Object> parameters = new HashMap<>(); parameters.put("book", 55000); parameters.put("pen", 11111.1111); JasperReport jasperReport = JasperCompileManager.compileReport(inputStream); JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, null, new JREmptyDataSource()); JasperExportManager.exportReportToPdfFile(jasperPrint, outputFilename);
這裡,因為我們直接填充,所以可以使用Map類別。如果你想從資料來源(Database,...)填入數據,可以參考(https://www.baeldung.com/spring-jasper)。
結果如下
3。安全編程
因為在渲染這個模板的過程中,庫也會執行其中的函數,所以如果使用者可以自訂模板標籤,攻擊者就會添加可以執行命令的惡意標籤。此錯誤與 SSTI 非常相似。
假設允許使用者直接編輯模板。原始碼如下:
final String outputFilename = "out.pdf"; Files.deleteIfExists(new File(outputFilename).toPath()); String input = ""; String template = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<jasperReport xmlns=\"http://jasperreports.sourceforge.net/jasperreports\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd\" name=\"z\" pageWidth=\"500\" pageHeight=\"1200\" columnWidth=\"270\">\n" + input + "</jasperReport>"; InputStream inputStream = new ByteArrayInputStream(template.getBytes()); JasperReport jasperReport = JasperCompileManager.compileReport(inputStream); JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, null, new JREmptyDataSource()); JasperExportManager.exportReportToPdfFile(jasperPrint, outputFilename);
攻擊者填入惡意函數來控制系統:
字串輸入=“ <p>結果,命令被執行。文件「out.pdf」包含以下內容:</p> <p><img src="https://img.php.cn/upload/article/000/000/000/173597147572303.jpg" alt="Giới thiệu căn bản về thư viện JasperReports"></p> <p>所以程式設計師也必須小心,不要讓使用者直接在模板中輸入內容。 <br> 另外,該程式庫在舊版中也存在漏洞(<em>CVE-2018-18809、CVE-2022-42889</em>、...),程式設計時應注意使用最新版本並更新。定期。 </p>
以上是JasperReports庫的基本介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!