介紹下pdf打印工具類 JasperPrint

JasperPrint 工具類深度解析

JasperPrint 是 JasperReports 框架中實現 PDF 打印的核心載體類,其本質是?填充數據后的可打印報表對象,承擔著從模板編譯、數據填充到格式輸出的全流程控制。以下從 7 個維度展開深度解析:


一、核心定位與生命周期
  1. 中間態實體角色
    JasperPrint 處于報表生成流程的中間階段(生命周期模型):
   JRXML(設計模板) → Jasper(編譯模板) → JasperPrint(填充數據) → PDF/Excel(導出)

其內存結構中包含:

  • 編譯后的模板元數據
  • 動態注入的參數集合(Map<String, Object>
  • 數據源綁定結果(JRDataSource
  1. 跨格式輸出樞紐
    支持通過?JasperExportManager?或?JRPdfExporter?導出為 PDF,也可適配 Excel/HTML 等其他格式,實現?一份填充數據多端復用?的特性。

二、核心功能實現
(一)數據填充
  1. 參數注入方式
   Map<String,Object> params = new HashMap<>();params.put("title", "2025年度報表");JasperPrint print = JasperFillManager.fillReport(jasperFile, params, dataSource);

運行

  • 支持基礎類型、POJO、圖片資源(需轉?InputStream
  • 參數作用域覆蓋整個報表生命周期
  1. 數據源綁定

    數據源類型適用場景代碼示例來源證據
    JRBeanCollectionDataSourceList 集合數據綁定new JRBeanCollectionDataSource(list)
    JREmptyDataSource無數據空報表生成new JREmptyDataSource()
    ResultSet直接數據庫查詢結果new JRResultSetDataSource(rs)
(二)打印控制
  1. 頁面布局配置
   PDFPrintable pdfPrintable = new PDFPrintable(print, Scaling.ACTUAL_SIZE);PageFormat pageFormat = new PageFormat();pageFormat.setOrientation(PageFormat.LANDSCAPE); // 橫向打印

運行

  • 支持縮放比例(Scaling.SHRINK_TO_FIT等)、紙張大小(pageFormat.setPaper()
  1. 批量打印管理
    通過?List<JasperPrint>?實現多文檔串聯打印,支持:
    • 頁碼連續編排
    • 書簽目錄生成(IS_CREATING_BATCH_MODE_BOOKMARKS參數)

三、PDF 導出實現
(一)基礎導出模式
  1. 快速導出法
   JasperExportManager.exportReportToPdfStream(print, outputStream); 

運行

  • 優點:代碼簡潔,自動處理字體嵌入
  • 缺點:無法定制加密等高級功能
  1. 精細化控制法
   JRPdfExporter exporter = new JRPdfExporter();exporter.setParameter(JRExporterParameter.JASPER_PRINT, print);exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, os);exporter.exportReport(); 

運行

  • 支持 PDF 加密(USER_PASSWORD/OWNER_PASSWORD
  • 可配置權限(打印/復制/修改等)
(二)中文處理方案
  1. 字體配置關鍵點
   net.sf.jasperreports.extension.registry.factory.simple.font.families=net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactorynet.sf.jasperreports.extension.simple.font.families.lobstertwo=stsong/fonts.xml
  • 必須包含中文字體文件(如?stsong.ttf
  • PDF 編碼需設置為?UniGB-UCS2-H
  1. 常見問題解決
    • 亂碼:檢查字體是否嵌入(PDF Embedded=true
    • 空白頁:調整?detail?區域高度避免溢出

四、企業級應用實踐
(一)SpringBoot 整合
  1. 工具類封裝
   public class JasperPdfUtil {public static byte[] export(Map<String,Object> params) throws JRException {JasperReport report = JasperCompileManager.compileReport("template.jrxml");JasperPrint print = JasperFillManager.fillReport(report, params, new JREmptyDataSource());return JasperExportManager.exportReportToPdf(print);}}

運行

  • 支持模板熱加載
  • 結合?ResponseEntity?實現 RESTful 輸出
  1. 動態模板方案
   Resource resource = new ClassPathResource("templates/"+templateName+".jasper");JasperPrint print = JasperFillManager.fillReport(resource.getInputStream(), params, dataSource);

運行

  • 模板路徑可配置化
  • 支持云端存儲模板(如 OSS)
(二)性能優化
  1. 內存控制策略

    • 啟用虛擬化模式(IS_IGNORE_PAGINATION?分頁優化)
    • 使用?JRFileVirtualizer?處理大報表
  2. 異步導出方案

   CompletableFuture.supplyAsync(() -> {return JasperExportManager.exportReportToPdf(print);}).thenAccept(pdfBytes -> {// 寫入消息隊列或OSS});

運行

  • 避免 HTTP 請求超時

五、特殊場景處理
  1. Base64 編碼輸出
   byte[] pdfBytes = JasperExportManager.exportReportToPdf(print);String base64Str = new BASE64Encoder().encode(pdfBytes);

運行

  • 前端渲染需添加?data:application/pdf;base64,?前綴
  • 需替換?+?為?%2B?防止傳輸錯誤
  1. 加密文檔生成
   exporter.setParameter(PdfExporterConfiguration.IS_ENCRYPTED, true);exporter.setParameter(PdfExporterConfiguration.USER_PASSWORD, "user123");exporter.setParameter(PdfExporterConfiguration.OWNER_PASSWORD, "admin456"); 

運行

  • 支持 128 位密鑰加密

六、調試與監控
  1. 日志追蹤配置
   <logger name="net.sf.jasperreports" level="DEBUG"/>
  • 可捕獲模板編譯錯誤、數據綁定異常
  1. 可視化預覽器
   JasperViewer.viewReport(print, false); // 彈出預覽窗口

運行

  • 本地調試時快速驗證布局

七、技術演進趨勢
  1. 云原生支持

    • 與 K8s 結合實現彈性擴縮容
    • 模板存儲從本地文件轉向 MinIO/OSS
  2. 智能化增強

    • 集成 AI 引擎自動優化報表布局
    • 動態參數推薦(基于歷史數據分析)

JasperPrint 工作流程圖

JasperPrint 工作流程圖


(流程圖示意:模板編譯 → 數據填充 → 打印控制 → 格式導出)


總結

JasperPrint 作為 JasperReports 生態中的?數據承載中樞,其核心價值在于解耦了模板設計與數據呈現。通過精準的參數控制、靈活的數據源適配以及深度的格式定制能力,使其成為企業級報表系統的首選方案。在云原生與 AI 技術驅動下,未來將向?動態化、服務化、智能化?方向持續演進。

分享

追問


相關組織

組織名稱概述

JasperSoft

軟件/技術一家提供報表工具JasperReport的公司,用于實現PDF打印。

TIBCO

軟件/技術提供Jaspersoft Studio軟件,用于繪制報表模板。

相關人物

人物名稱概述

junqiang.lu

開發者/程序員開發了JasperPdfUtil工具類的作者。

JasperPrint 支持哪些數據源?

JasperPrint 支持的數據源類型全解析

作為 JasperReports 框架的核心數據載體,JasperPrint 支持的數據源類型與其底層接口?JRDataSource?的實現密切相關。根據資料中的技術文檔和代碼實踐,其數據源支持體系可劃分為以下六類:


一、JDBC 數據庫連接(關系型數據源)

實現方式
通過?java.sql.Connection?對象直接傳遞 SQL 查詢結果,適用于傳統關系型數據庫(如 MySQL、Oracle)。

Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db", "user", "pass");
JasperPrint print = JasperFillManager.fillReport(jasperReport, params, conn); // 自動執行模板中的 SQL

運行

核心特征

  • 內置支持 JDBC 驅動(需在報表模板中預定義 SQL 查詢)
  • 支持動態參數化 SQL(通過?$P{param}?注入)

二、集合類數據源(JavaBean/List/Map)

實現方式

  1. JavaBean 集合:通過?JRBeanCollectionDataSource?轉換 List&lt;POJO&gt;
List<Customer> customers = customerDao.getAll();
JRDataSource ds = new JRBeanCollectionDataSource(customers);
JasperPrint print = JasperFillManager.fillReport(jasperReport, params, ds); // 自動映射字段名

運行

  1. Map 集合:直接傳遞?Map<String, Object>,適用于無結構化數據的場景
Map<String, Object> data = new HashMap<>();
data.put("sales", 50000);
JasperPrint print = JasperFillManager.fillReport(jasperReport, data, new JREmptyDataSource());

運行

核心特征

  • 字段名需與模板中的?$F{field}?嚴格匹配
  • 支持嵌套對象(如?$F{user.address.city}

三、空數據源(無數據填充)

實現方式
使用?JREmptyDataSource?生成無數據報表,常用于靜態參數展示。

JasperPrint print = JasperFillManager.fillReport(jasperReport, params, new JREmptyDataSource());

運行

應用場景

  • 生成僅含標題、頁腳的空白模板
  • 參數化動態內容(如圖片路徑、標題文本)

四、JSON 數據源(非結構化數據)

實現方式
通過?JsonQueryExecuterFactory?解析 JSON 輸入流,支持復雜嵌套結構。

InputStream jsonStream = new ByteArrayInputStream(jsonStr.getBytes());
params.put(JsonQueryExecuterFactory.JSON_INPUT_STREAM, jsonStream);
JasperPrint print = JasperFillManager.fillReport(jasperReport, params, new JREmptyDataSource());

運行

關鍵配置

  • 需在模板中定義 JSON 路徑表達式(如?$.users[0].name
  • 支持本地化參數(JSON_LOCALE)和日期格式化

五、文件類數據源(Excel/CSV/XML)

實現方式
通過自定義?JRDataSource?實現類解析文件,如:

  1. Excel 數據源:使用?JRXlsxDataSource
JRXlsxDataSource ds = new JRXlsxDataSource(new File("data.xlsx"));
ds.setSheetSelection(0); // 選擇工作表
JasperPrint print = JasperFillManager.fillReport(jasperReport, params, ds);

運行

  1. CSV 數據源:使用?JRCsvDataSource
JRCsvDataSource ds = new JRCsvDataSource(new File("data.csv"));
ds.setColumnNames(new String[]{"id", "name"}); // 定義列名

運行

核心特征

  • 需引入?jasperreports-components?依賴
  • 支持分頁讀取大文件

六、自定義數據源(擴展接口)

實現方式
繼承?JRDataSource?接口,處理特殊數據格式(如 NoSQL、API 接口)。

public class CustomDataSource implements JRDataSource {private Iterator<Data> iterator;public boolean next() { return iterator.hasNext(); }public Object getFieldValue(JRField field) {return iterator.next().get(field.getName());}
}
// 使用
JasperPrint print = JasperFillManager.fillReport(jasperReport, params, new CustomDataSource(data));

運行

典型應用

  • MongoDB 文檔集合
  • REST API 分頁響應

數據源選擇決策矩陣

數據類型適用場景性能表現開發復雜度引用來源
JDBC結構化數據庫報表★★★★☆★★☆☆☆
JavaBean集合POJO 業務對象導出★★★★☆★☆☆☆☆
JSON微服務接口數據聚合★★★☆☆★★★☆☆
文件類離線數據批量處理★★☆☆☆★★★★☆
自定義非標系統集成★☆☆☆☆★★★★★

高級數據源特性

  1. 混合數據源
    支持主報表與子報表使用不同數據源(如主表用 JDBC,子表用 JSON):
   <subreport><dataSourceExpression><![CDATA[new JsonDataSource($P{API_DATA})]]></dataSourceExpression></subreport>
  1. 動態數據切換
    通過?JRFillParameter?在運行時切換數據源:
   params.put(JRParameter.REPORT_DATA_SOURCE, ds1); // 初始數據源if (condition) params.replace(JRParameter.REPORT_DATA_SOURCE, ds2);

運行

  1. 虛擬化大數據集
    使用?JRFileVirtualizer?分頁加載海量數據,避免內存溢出:
   JRVirtualizer virtualizer = new JRFileVirtualizer(100); // 每頁100條params.put(JRParameter.REPORT_VIRTUALIZER, virtualizer);

運行


常見問題解決方案

  1. 空指針異常

    • 確保數據源不為?null,即使使用空數據源也需顯式創建?JREmptyDataSource
    • 檢查模板字段名與數據源屬性大小寫是否一致
  2. 性能優化

    • 啟用分頁模式:params.put(JRParameter.IS_IGNORE_PAGINATION, false)
    • 對 JDBC 數據源添加 SQL 分頁查詢
  3. 編碼問題

    • JSON/CSV 數據源需統一使用 UTF-8 編碼
    • 中文字體需在?jasperreports.properties?中注冊

演進趨勢

  1. 云原生數據源
    支持從 AWS S3、阿里云 OSS 直接讀取文件
   OSSDataSource ds = new OSSDataSource("oss://bucket/report-data.csv");

運行

  1. 流式處理
    通過 Reactive Streams 實現實時數據推送
   Flux<Data> flux = service.getStreamingData();JasperPrint print = JasperFillManager.fillReport(jasperReport, params, new FluxDataSource(flux));

運行

  1. AI 增強
    自動推斷數據源結構并生成適配模板
   AIDataSourceAnalyzer.analyze(ds).generateTemplate();

運行

通過靈活選擇數據源類型并優化實現,JasperPrint 可覆蓋從傳統數據庫到現代數據湖的全場景報表需求,其擴展性設計(如自定義?JRDataSource)為復雜企業級應用提供了堅實基礎

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/71979.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/71979.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/71979.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

LVS+Keepalived 高可用集群搭建

一、高可用集群&#xff1a; 1.什么是高可用集群&#xff1a; 高可用集群&#xff08;High Availability Cluster&#xff09;是以減少服務中斷時間為目地的服務器集群技術它通過保護用戶的業務程序對外不間斷提供的服務&#xff0c;把因軟件、硬件、人為造成的故障對業務的影響…

從【人工智能】到【計算機視覺】,【深度學習】引領的未來科技創新與變革

前幾天偶然發現了一個超棒的人工智能學習網站&#xff0c;內容通俗易懂&#xff0c;講解風趣幽默&#xff0c;簡直讓人欲罷不能。忍不住分享給大家&#xff0c;點擊這里立刻跳轉&#xff0c;開啟你的AI學習之旅吧&#xff01; 前言 – 人工智能教程https://www.captainbed.cn/l…

銀河麒麟高級服務器操作系統在線調整/pro/{PID}/limits文件中nofile的軟限制和硬限制參數值操作方法

銀河麒麟高級服務器操作系統在線調整/pro/{PID}/limits文件中nofile的軟限制和硬限制參數值操作方法 一 系統環境二 使用場景三 操作步驟 一 系統環境 [rootlocalhost ~]# nkvers ############## Kylin Linux Version ################# Release: Kylin Linux Advanced Server…

數據結構-直接插入和希爾排序

這次&#xff0c;我們來講數據結構的排序的直接插入。 一&#xff1a;排序的思想&#xff1a;把待排序的記錄按其關鍵碼值的大小逐個插入到一個已經排好序的有序序列中&#xff0c;直到所有的記錄插入完為止&#xff0c;得到一個新的有序序列 相當于&#xff0c;我們打牌如上圖…

基于coze+微信小程序的ai對話

界面介紹&#xff1a; 代碼&#xff1a;&#xff08;替換你的coze的配置&#xff09; <template><view class"container"><!-- 高斯模糊背景 --><view class"animated-bg"><view class"gradient-blob"></view…

Day11,Hot100(貪心算法)

貪心 &#xff08;1&#xff09;121. 買賣股票的最佳時機 第 i 天賣出的最大利潤&#xff0c;即在前面最低價的時候買入 class Solution:def maxProfit(self, prices: List[int]) -> int:min_price prices[0]ans 0for price in prices:ans max(ans, price - min_price…

Linux內核自定義協議族開發指南:理解net_device_ops、proto_ops與net_proto_family

在Linux內核中開發自定義協議族需要深入理解網絡協議棧的分層模型。net_device_ops、proto_ops和net_proto_family是三個關鍵結構體,分別作用于不同的層次。本文將詳細解析它們的作用、交互關系及實現方法,并提供一個完整的開發框架。 一、核心結構體的作用與層級關系 struct…

SpringBoot 中的 Redis 序列化

SpringBoot 中的 Redis 序列化 在 Spring Boot 中&#xff0c;Redis 的序列化是指將 Java 對象轉換為字節流&#xff08;序列化&#xff09;以便存儲到 Redis 中&#xff0c;以及從 Redis 中讀取字節流并將其轉換回 Java 對象&#xff08;反序列化&#xff09;。 這是因為在 R…

vLLM服務設置開機自啟動(Linux)

要在開機時進入指定的 conda 環境并啟動此 vllm 服務&#xff0c;您可以通過以下步驟設置一個 systemd 服務來自動執行腳本。 一、第一步&#xff1a;創建一個啟動腳本 1.打開終端并創建啟動腳本&#xff0c;例如 /home/username/start_vllm.sh&#xff08;請替換 username 為…

AI繪畫軟件Stable Diffusion詳解教程(3):Windows系統本地化部署操作方法(通用版)

上一篇教程介紹了如何在本地部署Stable Diffusion專業版&#xff0c;雖然便于技術人員研究&#xff0c;但是普通人使用起來不便捷&#xff0c;每次只能通過cmd窗口的指令形式或者python代碼方式來畫圖&#xff0c;要記很多的指令很繁瑣。 本篇教程教您搭建webui版的&#xff0…

大數據SQL調優專題——調優切入

引入 我們都知道大數據的SQL優化&#xff0c;并非一蹴而就的簡單任務&#xff0c;而是一個涉及多個環節的復雜過程。雖然我們的專欄名字叫大數據SQL調優&#xff0c;但是調優并不是簡單對SQL優化&#xff0c;而是一個涉及多個環節的復雜過程。實際上從需求接入到最終交付&…

貪心算法精品題

1.找錢問題 本題的貪心策略在于我們希望就可能的保留作用大的5元 class Solution { public:bool lemonadeChange(vector<int>& bills) {std::map<int ,int> _map;for(auto ch:bills){if(ch 5) _map[ch];else if(ch 10){if(_map[5] 0) return false;else{_m…

spring結合mybatis多租戶實現單庫分表

實現單庫分表 思路&#xff1a;student表數據量大&#xff0c;所以將其進行分表處理。一共有三個分表&#xff0c;分別是student0&#xff0c;student1&#xff0c;student2&#xff0c;在新增數據的時候&#xff0c;根據請求頭中的meta-tenant參數決定數據存在哪張表表。 數…

Ecode前后端傳值

說明 在泛微 E9 系統開發過程中&#xff0c;使用 Ecode 調用后端接口并進行傳值是極為常見且關鍵的操作。在上一篇文章中&#xff0c;我們探討了 Ecode 調用后端代碼的相關內容&#xff0c;本文將深入剖析在 Ecode 中如何向后端傳值&#xff0c;以及后端又該如何處理接收這些值…

黑馬Java面試教程_P5_微服務

系列博客目錄 文章目錄 系列博客目錄1.引言2.Spring Cloud2.1 Spring Cloud 5大組件有哪些?面試文稿 2.2 服務注冊和發現是什么意思?Spring Cloud 如何實現服務注冊發現?面試文稿 2.3 我看你之前也用過nacos、你能說下nacos與eureka的區別?面試文稿 2.4 你們項目負載均衡如…

【2025深度學習環境搭建-2】pytorch+Docker+VS Code+DevContainer搭建本地深度學習環境

上一篇文章&#xff1a;【2025深度學習環境搭建-1】在Win11上用WSL2和Docker解鎖GPU加速 先啟動Docker&#xff01;對文件內容有疑問&#xff0c;就去問AI 一、用Docker拉取pytorch鏡像&#xff0c;啟動容器&#xff0c;測試GPU docker pull pytorch/pytorch:2.5.0-cuda12.4…

Linux驅動開發實戰(一):LED控制驅動詳解

Linux驅動開發野火實戰&#xff08;一&#xff09;&#xff1a;LED控制驅動詳解 文章目錄 Linux驅動開發野火實戰&#xff08;一&#xff09;&#xff1a;LED控制驅動詳解引言一、基礎知識1.1 什么是字符設備驅動1.2 重要的數據結構read 函數write 函數open 函數release 函數 二…

Linux上用C++和GCC開發程序實現不同MySQL實例下單個Schema之間的穩定高效的數據遷移

設計一個在Linux上運行的GCC C程序&#xff0c;同時連接兩個不同的MySQL實例&#xff0c;兩個實例中分別有兩個Schema的表結構完全相同&#xff0c;復制一個實例中一個Schema里的所有表的數據到另一個實例中一個Schema里&#xff0c;使用以下快速高效的方法&#xff0c;加入異常…

Redis除了做緩存還能做什么?

Redis 除了作為高性能緩存外&#xff0c;還因其豐富的數據結構和功能&#xff0c;廣泛應用于多種場景。以下是 Redis 的十大核心用途及具體示例&#xff1a; 1. 分布式會話存儲 用途&#xff1a;存儲用戶會話信息&#xff08;如登錄狀態&#xff09;&#xff0c;實現多服務間共…

JBoltAI_SpringBoot如何區分DeepSeek R1深度思考和具體回答的內容(基于Ollama)?

當我們用Ollama運行DeepSeek R1模型&#xff0c;向它提問時&#xff0c;會發現它的回答里是有think標簽的 如果我們直接將Ollama的回復用于生產環境&#xff0c;肯定是不行的&#xff0c;對于不同的場景&#xff0c;前面輸出的一堆內容&#xff0c;可能并不需要在客戶端展示&a…