談談Java報表之JasperReport改造一,動態報表
我本對JasperReport一殼不同,只是公司在做產品時選用了JasperReport,主要原因還是免費吧!由於公司是做物流系統,所以對於報表的要求非常高,大體在使用JasperReport過程中分為兩類,一類是類似表單形式,還有一類就是傳統的彙總報表。其中表單形式十分多,主要用於物流行業中的各種單據列印,比如報關單,發票等等。
國內客戶有一個很奇怪的需求,就是喜歡在列印預攬時修改單據的資料(有可能是要做假脹的原因)或者修改具體的表單佈局,我們公司遇到這樣的情況非常多。JasperReport是透過xml檔案記錄具體的佈局資訊,一般也是用同樣開源的IReport產生編輯一個具體的JasperReport的佈局xml資訊。如果我們需要實現客戶的功能,乍看起來,等於是要實現一個IReport中的編輯功能。老闆要求我來實現,經過幾天的研究,發現其實不然,實現在JasperReport良好的封裝的基礎上實現這樣的功能不用很費力。
下面我介紹一下簡單原理:
JasperReport提供一個JRViewer的預攬元件,是一個JPanel物件。在JRViewer繪製預攬效果時,會呼叫
JasperPrintManager.printPageToImage(jasperPrint, pageIndex, realZoom, viewer.isDesignMode);方法得到一個Image物件(雙緩衝),然後再將Image物件setIcon給JRViewer上面的顯示元件。所以預攬效果最終是靠Image物件呈現,需要動態抓取Image物件中具體的報表資料元素的位置是非常困難,我沒有走這條路。其實在JasperReport中每一個圖形元素都是一個JRPrintElement介面的例項物件,圖形元素的位置,資料,字型等等資訊都放在JasperPrint中都包含了這些物件。JasperPrintManager.printPageToImage(jasperPrint, pageIndex, realZoom, viewer.isDesignMode);最終會呼叫JRGraphics2DExporter中的exportElements(Collection elements)遍例JasperPrint物件中的JRPrintElement分別透過最後輸出的Graghic2D控制程式碼繪製圖形,文字。我的解決方案就是從JasperPrint物件下手。
1)給JRViewer上面的顯示圖例元件加MouseListener,MouseMotionAdapter
2)在mousePress中,透過MouseEvent得到當前滑鼠的位置,並且透過遍例當前JasperPrint中的所有JRPrintElement的getX,getY,getWidth,getHeight來拿到當前的JRPrintElement物件,並且記入下來(在使用橡皮帶技術時需要重化上一個圖形的位置,具體演算法太過複雜這裡忽略介紹)。
3)在mouseDragged方法中,實現橡皮帶技術(其實就是畫一個虛框,感覺圖形在跟著滑鼠動)。
4)在mouseRelease方法中,得到release的位置,包括x,y座標和最後釋放矩形的width,height。
5)JRPrintElement物件中沒有setX,setY,setWidth,setHeight介面,所以需要改動原始碼,加上這些方法。在JRTemplatePrintElement或者JRBasePrintElement中改變例項的x,y,width,height。
6)重新呼叫JasperPrintManager.printPageToImage(jasperPrint, pageIndex, realZoom, viewer.isDesignMode);雙緩衝使頁面重新整理不會有多大抖動的感覺。
這樣就可以動態調整圖形元素的位置佈局。
7)在mousePress中加入e.getClickCount==2的雙擊判斷,對於大多數顯示文字的JRPrintElement都是JRPrintText的子類,(JRPrintText在最早的原始碼有沒有setText我記不清了,如果沒有的話也加上setText介面)JRPrintTemplateText和JRBasePrintText都有text這個變數,在setText改變text的值,同樣呼叫JasperPrintManager.printPageToImage(jasperPrint, pageIndex, realZoom, viewer.isDesignMode);就可以看到改變後的效果。
小結:這裡我只是簡單介紹一下動態報表的實現,其實只要看清JasperReport原始碼的一些結構會發現,其物件導向設計做的非常好,還可以有很多改造的餘地。後面我還會介紹如何實現將修改後的佈局保留成新的xml,以及無窮層子報表的實現。
順便說一句:客戶使用動態報表和開心,他們甚至要我們在開發財務發票模組時,提供一張空白報表,只留一些空白的資料圖形元素,然後列印發票前直接填入發票金額,估計這種事情也只有國內客戶才做得出來,呵呵!
國內客戶有一個很奇怪的需求,就是喜歡在列印預攬時修改單據的資料(有可能是要做假脹的原因)或者修改具體的表單佈局,我們公司遇到這樣的情況非常多。JasperReport是透過xml檔案記錄具體的佈局資訊,一般也是用同樣開源的IReport產生編輯一個具體的JasperReport的佈局xml資訊。如果我們需要實現客戶的功能,乍看起來,等於是要實現一個IReport中的編輯功能。老闆要求我來實現,經過幾天的研究,發現其實不然,實現在JasperReport良好的封裝的基礎上實現這樣的功能不用很費力。
下面我介紹一下簡單原理:
JasperReport提供一個JRViewer的預攬元件,是一個JPanel物件。在JRViewer繪製預攬效果時,會呼叫
JasperPrintManager.printPageToImage(jasperPrint, pageIndex, realZoom, viewer.isDesignMode);方法得到一個Image物件(雙緩衝),然後再將Image物件setIcon給JRViewer上面的顯示元件。所以預攬效果最終是靠Image物件呈現,需要動態抓取Image物件中具體的報表資料元素的位置是非常困難,我沒有走這條路。其實在JasperReport中每一個圖形元素都是一個JRPrintElement介面的例項物件,圖形元素的位置,資料,字型等等資訊都放在JasperPrint中都包含了這些物件。JasperPrintManager.printPageToImage(jasperPrint, pageIndex, realZoom, viewer.isDesignMode);最終會呼叫JRGraphics2DExporter中的exportElements(Collection elements)遍例JasperPrint物件中的JRPrintElement分別透過最後輸出的Graghic2D控制程式碼繪製圖形,文字。我的解決方案就是從JasperPrint物件下手。
1)給JRViewer上面的顯示圖例元件加MouseListener,MouseMotionAdapter
2)在mousePress中,透過MouseEvent得到當前滑鼠的位置,並且透過遍例當前JasperPrint中的所有JRPrintElement的getX,getY,getWidth,getHeight來拿到當前的JRPrintElement物件,並且記入下來(在使用橡皮帶技術時需要重化上一個圖形的位置,具體演算法太過複雜這裡忽略介紹)。
3)在mouseDragged方法中,實現橡皮帶技術(其實就是畫一個虛框,感覺圖形在跟著滑鼠動)。
4)在mouseRelease方法中,得到release的位置,包括x,y座標和最後釋放矩形的width,height。
5)JRPrintElement物件中沒有setX,setY,setWidth,setHeight介面,所以需要改動原始碼,加上這些方法。在JRTemplatePrintElement或者JRBasePrintElement中改變例項的x,y,width,height。
6)重新呼叫JasperPrintManager.printPageToImage(jasperPrint, pageIndex, realZoom, viewer.isDesignMode);雙緩衝使頁面重新整理不會有多大抖動的感覺。
這樣就可以動態調整圖形元素的位置佈局。
7)在mousePress中加入e.getClickCount==2的雙擊判斷,對於大多數顯示文字的JRPrintElement都是JRPrintText的子類,(JRPrintText在最早的原始碼有沒有setText我記不清了,如果沒有的話也加上setText介面)JRPrintTemplateText和JRBasePrintText都有text這個變數,在setText改變text的值,同樣呼叫JasperPrintManager.printPageToImage(jasperPrint, pageIndex, realZoom, viewer.isDesignMode);就可以看到改變後的效果。
小結:這裡我只是簡單介紹一下動態報表的實現,其實只要看清JasperReport原始碼的一些結構會發現,其物件導向設計做的非常好,還可以有很多改造的餘地。後面我還會介紹如何實現將修改後的佈局保留成新的xml,以及無窮層子報表的實現。
順便說一句:客戶使用動態報表和開心,他們甚至要我們在開發財務發票模組時,提供一張空白報表,只留一些空白的資料圖形元素,然後列印發票前直接填入發票金額,估計這種事情也只有國內客戶才做得出來,呵呵!
相關文章
- Jasperreport 報表開發
- 複雜報表設計之動態報表
- 動態sql 報表SQL
- Java開源報表JasperReport、iReport4.5.1使用詳解(一)Java
- ActiveReports 報表應用教程 (9)---互動式報表之動態排序排序
- ActiveReports 報表應用教程 (8)---互動式報表之動態過濾
- 怎麼製作動態列報表(非常規交叉表)
- 談一談動態規劃和dfs動態規劃
- JasperReport報表生成工具的基本使用和常見問題
- 怎樣實現動態列報表,也就是列數不固定的報表?
- ActiveReports 報表應用教程 (11)---互動式報表之文件目錄
- 舊的報表平臺滿足不了需求?使用者說固定報表和動態報表兩個都想要
- 報表中怎麼新增動態文字水印
- 如何製作動態層分組報表
- 皕傑報表之填報操作
- 談談面試--雜湊表系列面試
- 如何在水晶報表中動態新增欄位
- 報表工具對比之潤乾報表與銳浪報表對比
- 統計報表中動態增加列的解決方法之一
- EBS 單個報表(非報表集)根據報表名稱獲取報表源程式
- 報表怎麼動態選擇資料來源
- 請教個動態報表設計的問題
- DynamicReports:Java快速報表元件Java元件
- 淺談雜湊表
- ActiveReports 報表應用教程 (3)---圖表報表
- iReport 報表、子報表、主從報表、合計、例項解析
- LR.JAVA報表設計器,快速點亮報表設計技能Java
- Redmine之報表應用研究
- 談談什麼是MySQL的表空間?MySql
- 談談為什麼要分庫分表?
- 談談如何抓取ajax動態網站網站
- 淺談表單設計
- 填報表之資料留痕
- NPOI之使用EXCEL模板建立報表Excel
- 分欄報表-物品清單報表實現
- 動態切換 web 報表中的統計圖型別Web型別
- 在VB6.0中實現動態統計報表 (轉)
- 有什麼工具能生成帶有動態報表圖形的 word 報告嗎?