1。簡(jiǎn)介
在實(shí)踐中,我們看到以某種格式統(tǒng)計(jì)和導(dǎo)出數(shù)據(jù)的請(qǐng)求是很常見(jiàn)的。例如,我們收到導(dǎo)出客戶統(tǒng)計(jì)報(bào)告、銷售發(fā)票、采購(gòu)發(fā)票等的請(qǐng)求,這需要人們(尤其是程序員)創(chuàng)建軟件,您可以根據(jù)每個(gè)具體情況和要求靈活創(chuàng)建導(dǎo)出數(shù)據(jù)的模板。你可能立刻想到的解決方案是使用Word、Excel……,但是這種解決方案不適合大量不斷變化、短時(shí)間內(nèi)發(fā)展的數(shù)據(jù),同時(shí)還需要支付軟件費(fèi)用和數(shù)據(jù)處理時(shí)間不是最佳的。
目前有一個(gè)相當(dāng)流行的解決方案——很多程序員都喜歡使用的JasperReports庫(kù)。
特別是,這個(gè)庫(kù)是開(kāi)源的,并且有免費(fèi)版本。您可以訪問(wèn)其源代碼:https://github.com/TIBCOSoftware/jasperreports
2。使用說(shuō)明
關(guān)于如何使用這個(gè)庫(kù)網(wǎng)上有很多說(shuō)明,這里就不詳細(xì)寫(xiě)了
如果您使用 Eclipse,JasperReports 有一個(gè)額外的插件可以幫助您創(chuàng)建報(bào)告模板。
在這篇文章中,我將指導(dǎo)您在IntelliJ IDEA上使用它,庫(kù)管理器是maven。
首先,您需要一個(gè)模板來(lái)填寫(xiě)數(shù)據(jù)(如訂單、發(fā)票等)。為此,請(qǐng)下載并安裝 Jaspersoft Studio 軟件(最新的社區(qū)版本鏈接當(dāng)前為 https://community.jaspersoft.com/files/file/19-jaspersoft?-studio-community-edition /?do=getNewComment)。
安裝并打開(kāi)后,軟件會(huì)有如下界面:
要?jiǎng)?chuàng)建新模板,請(qǐng)轉(zhuǎn)到文件 ->新->賈斯珀報(bào)告。在“全部”部分中,選擇“空白 A4”(或您喜歡的其他模板:>)。
單擊“下一步”,指定文件的保存位置。點(diǎn)擊下一步->下一步->結(jié)束。出現(xiàn)的新界面是模板界面,您可以根據(jù)自己的模板自由設(shè)計(jì)。
右側(cè)是庫(kù)支持的對(duì)象。
假設(shè)我必須創(chuàng)建一個(gè)帶有標(biāo)題和商品名稱的簡(jiǎn)單購(gòu)買發(fā)票表格。我將“靜態(tài)文本”對(duì)象拖放到模板中,并輸入名稱“采購(gòu)發(fā)票”(您可以在屏幕右上角自行調(diào)整格式)。
接下來(lái),我再拖動(dòng) 2 個(gè)類似的對(duì)象,但將項(xiàng)目類別設(shè)置在“書(shū)籍”和“鋼筆”下方。
接下來(lái)我必須添加這 2 件商品的價(jià)格。這個(gè)值是動(dòng)態(tài)的,所以我必須在這里包含一個(gè)變量(這也是這個(gè)庫(kù)的一個(gè)非常有趣和靈活的功能)。在大綱部分、參數(shù)部分中,右鍵單擊并選擇“創(chuàng)建參數(shù)”。然后我在右角窗口修改了這個(gè)變量的值,變量名為book,數(shù)據(jù)類型為實(shí)數(shù)。
然后我將其拖放到“Book”標(biāo)簽旁邊。與變量“筆”和總量相同。這里你可以分配的總金額等于變量“book”和“pen”的總和。
完成模板后,它會(huì)是這樣的
您切換到源選項(xiàng)卡,這是系統(tǒng)將處理的數(shù)據(jù)?;旧?,Jasper Report 將以類似于 XML 的文件格式接收輸入數(shù)據(jù),但標(biāo)簽名稱將由庫(kù)預(yù)先定義。例如,整個(gè)文件的超類的開(kāi)始和結(jié)束標(biāo)記必須是“jasperReport”標(biāo)記。以下是一些必須注意的模板符號(hào):
- “$P{}”:動(dòng)態(tài)添加到報(bào)表中的數(shù)據(jù),可以是鍵值對(duì),可以是數(shù)據(jù)源。
- “$F{}”:從數(shù)據(jù)源添加到報(bào)告的復(fù)雜數(shù)據(jù)字段。
- “$V{}”:根據(jù)現(xiàn)有表達(dá)式自動(dòng)生成數(shù)據(jù)或手動(dòng)添加數(shù)據(jù)。 ... 您可以參考更多信息(https://www.tutorialspoint.com/jasper_reports/jasper_report_expression.htm)
完成后,您可以開(kāi)始將此文件復(fù)制到您的項(xiàng)目中以填充數(shù)據(jù)并進(jìn)行處理。
然后繼續(xù)導(dǎo)入以下庫(kù):
<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>
繼續(xù)編寫(xiě)代碼導(dǎo)入文件并填充數(shù)據(jù)。
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);
這里,因?yàn)槲覀冎苯犹畛?,所以可以使用Map類。如果你想從數(shù)據(jù)源(Database,...)填充數(shù)據(jù),可以參考(https://www.baeldung.com/spring-jasper)。
結(jié)果如下
3。安全編程
因?yàn)樵阡秩具@個(gè)模板的過(guò)程中,庫(kù)也會(huì)執(zhí)行其中的函數(shù),所以如果用戶可以自定義模板標(biāo)簽,攻擊者就會(huì)添加可以執(zhí)行命令的惡意標(biāo)簽。此錯(cuò)誤與 SSTI 非常相似。
假設(shè)允許用戶直接編輯模板。源碼如下:
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);
攻擊者填充惡意函數(shù)來(lái)控制系統(tǒng):
字符串輸入=“ <p>結(jié)果,命令被執(zhí)行。文件“out.pdf”包含以下內(nèi)容:</p> <p><img src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/173597147572303.jpg" class="lazy" alt="Gi?i thi?u c?n b?n v? th? vi?n JasperReports"></p> <p>所以程序員也必須小心,不要讓用戶直接在模板中輸入內(nèi)容。<br> 另外,該庫(kù)在舊版本中也存在漏洞(<em>CVE-2018-18809、CVE-2022-42889</em>、...),編程時(shí)應(yīng)注意使用最新版本并更新。定期。</p>
以上是JasperReports庫(kù)的基本介紹的詳細(xì)內(nèi)容。更多信息請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

熱AI工具

Undress AI Tool
免費(fèi)脫衣服圖片

Undresser.AI Undress
人工智能驅(qū)動(dòng)的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover
用于從照片中去除衣服的在線人工智能工具。

Clothoff.io
AI脫衣機(jī)

Video Face Swap
使用我們完全免費(fèi)的人工智能換臉工具輕松在任何視頻中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費(fèi)的代碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
功能強(qiáng)大的PHP集成開(kāi)發(fā)環(huán)境

Dreamweaver CS6
視覺(jué)化網(wǎng)頁(yè)開(kāi)發(fā)工具

SublimeText3 Mac版
神級(jí)代碼編輯軟件(SublimeText3)

Callable和Runnable在Java中主要有三點(diǎn)區(qū)別。第一,Callable的call()方法可以返回結(jié)果,適合需要返回值的任務(wù),如Callable;而Runnable的run()方法無(wú)返回值,適用于無(wú)需返回的任務(wù),如日志記錄。第二,Callable允許拋出checked異常,便于錯(cuò)誤傳遞;而Runnable必須在內(nèi)部處理異常。第三,Runnable可直接傳給Thread或ExecutorService,而Callable只能提交給ExecutorService,并返回Future對(duì)象以

Java支持異步編程的方式包括使用CompletableFuture、響應(yīng)式流(如ProjectReactor)以及Java19 中的虛擬線程。1.CompletableFuture通過(guò)鏈?zhǔn)秸{(diào)用提升代碼可讀性和維護(hù)性,支持任務(wù)編排和異常處理;2.ProjectReactor提供Mono和Flux類型實(shí)現(xiàn)響應(yīng)式編程,具備背壓機(jī)制和豐富的操作符;3.虛擬線程減少并發(fā)成本,適用于I/O密集型任務(wù),與傳統(tǒng)平臺(tái)線程相比更輕量且易于擴(kuò)展。每種方式均有適用場(chǎng)景,應(yīng)根據(jù)需求選擇合適工具并避免混合模型以保持簡(jiǎn)潔性

JavaNIO是Java1.4引入的新型IOAPI,1)面向緩沖區(qū)和通道,2)包含Buffer、Channel和Selector核心組件,3)支持非阻塞模式,4)相比傳統(tǒng)IO更高效處理并發(fā)連接。其優(yōu)勢(shì)體現(xiàn)在:1)非阻塞IO減少線程開(kāi)銷,2)Buffer提升數(shù)據(jù)傳輸效率,3)Selector實(shí)現(xiàn)多路復(fù)用,4)內(nèi)存映射加快文件讀寫(xiě)。使用時(shí)需注意:1)Buffer的flip/clear操作易混淆,2)非阻塞下需手動(dòng)處理不完整數(shù)據(jù),3)Selector注冊(cè)需及時(shí)取消,4)NIO并非適用于所有場(chǎng)景。

在Java中,枚舉(enum)適合表示固定常量集合,最佳實(shí)踐包括:1.用enum表示固定狀態(tài)或選項(xiàng),提升類型安全和可讀性;2.為枚舉添加屬性和方法以增強(qiáng)靈活性,如定義字段、構(gòu)造函數(shù)、輔助方法等;3.使用EnumMap和EnumSet提高性能和類型安全性,因其基于數(shù)組實(shí)現(xiàn)更高效;4.避免濫用enum,如動(dòng)態(tài)值、頻繁變更或復(fù)雜邏輯場(chǎng)景應(yīng)使用其他方式替代。正確使用enum能提升代碼質(zhì)量并減少錯(cuò)誤,但需注意其適用邊界。

Java的類加載機(jī)制通過(guò)ClassLoader實(shí)現(xiàn),其核心工作流程分為加載、鏈接和初始化三個(gè)階段。加載階段由ClassLoader動(dòng)態(tài)讀取類的字節(jié)碼并創(chuàng)建Class對(duì)象;鏈接包括驗(yàn)證類的正確性、為靜態(tài)變量分配內(nèi)存及解析符號(hào)引用;初始化則執(zhí)行靜態(tài)代碼塊和靜態(tài)變量賦值。類加載采用雙親委派模型,優(yōu)先委托父類加載器查找類,依次嘗試Bootstrap、Extension和ApplicationClassLoader,確保核心類庫(kù)安全且避免重復(fù)加載。開(kāi)發(fā)者可自定義ClassLoader,如URLClassL

Javaprovidesmultiplesynchronizationtoolsforthreadsafety.1.synchronizedblocksensuremutualexclusionbylockingmethodsorspecificcodesections.2.ReentrantLockoffersadvancedcontrol,includingtryLockandfairnesspolicies.3.Conditionvariablesallowthreadstowaitfor

Java異常處理的關(guān)鍵在于區(qū)分checked和unchecked異常并合理使用try-catch、finally及日志記錄。1.checked異常如IOException需強(qiáng)制處理,適用于可預(yù)期的外部問(wèn)題;2.unchecked異常如NullPointerException通常由程序邏輯錯(cuò)誤引起,屬于運(yùn)行時(shí)錯(cuò)誤;3.捕獲異常時(shí)應(yīng)具體明確,避免籠統(tǒng)捕獲Exception;4.推薦使用try-with-resources自動(dòng)關(guān)閉資源,減少手動(dòng)清理代碼;5.異常處理中應(yīng)結(jié)合日志框架記錄詳細(xì)信息,便于后

HashMap在Java中通過(guò)哈希表實(shí)現(xiàn)鍵值對(duì)存儲(chǔ),其核心在于快速定位數(shù)據(jù)位置。1.首先使用鍵的hashCode()方法生成哈希值,并通過(guò)位運(yùn)算轉(zhuǎn)換為數(shù)組索引;2.不同對(duì)象可能產(chǎn)生相同哈希值,導(dǎo)致沖突,此時(shí)以鏈表形式掛載節(jié)點(diǎn),JDK8后鏈表過(guò)長(zhǎng)(默認(rèn)長(zhǎng)度8)則轉(zhuǎn)為紅黑樹(shù)提升效率;3.使用自定義類作鍵時(shí)必須重寫(xiě)equals()和hashCode()方法;4.HashMap動(dòng)態(tài)擴(kuò)容,當(dāng)元素?cái)?shù)超過(guò)容量乘以負(fù)載因子(默認(rèn)0.75)時(shí),擴(kuò)容并重新哈希;5.HashMap非線程安全,多線程下應(yīng)使用Concu
