最近公司新項目上有一個新的需要,即在原來用jasper打印出來的文檔上面,加上一個可以進(jìn)行識別的東西(暫定為條形碼),然后對這個文檔的掃描件進(jìn)行識別。初步確定就是修改原有的jasper資源文件,并在打印方法中加入一個對條形碼的field引用,這樣來完成在文檔上打印條形碼的需求。
但后面這一需要進(jìn)一步修正,因為要將掃描件保存入數(shù)據(jù)庫中,這時就想到如果不通過掃描設(shè)備,而直接將jasper在客戶端調(diào)出打印的時候,由服務(wù)器端生成一個jasper圖像,再將這個圖像直接入庫。這樣就避免了二次掃描的麻煩。
在網(wǎng)上google了一下關(guān)于jasperReport的應(yīng)用,發(fā)現(xiàn)大部分都是講如何將jasper導(dǎo)入一個html或pdf進(jìn)行打印的例子,并沒有直接將jasperReport打印生成一個圖像的示例。包括jaspe自帶的demo里面,也沒有相應(yīng)的例子,決定自己看看相應(yīng)的api,找一個可以運(yùn)用的東西。
產(chǎn)生想到的是jasper自帶的ImageServlet這個類,認(rèn)為可以從這個類方法中找到一些可以參考的東西??上⒋a粗略看一道,就失望了。這個類不是將一個jasper輸出一個圖像文件,而是輸出一個jasper文件中指定圖像名稱中的圖像信息。也就是說,這個類根本不能將一個jasper完整輸出成一個圖像的byte[]數(shù)組。看完這個類,我還真不知道這個類有什么樣,至少現(xiàn)在我不看好這個類。
接到就找export包中的相應(yīng)類,看能否找到一個根圖像有關(guān)的exporter,最后找到這樣一個類:JRGraphics2DExporter.java,從文檔可以看出,它可以完整的將一個jasper文檔輸出到一個graphics對象中,而不像其他的exporter只是近似的模擬。但是這個文檔同時也說明,它只是輸出到graphics對象,而不是輸出到一個文件或字節(jié)流中。當(dāng)然這不是問題,我們可以創(chuàng)建一個可以產(chǎn)生graphics的對象(比如說bufferedimage),然后用g進(jìn)行export,當(dāng)然最后的信息就保存在擁有g(shù)的對象上了。接下來的操作就簡單了。
如下代碼所示:
由上可以看出,和普通的htmlexporter一樣,產(chǎn)生創(chuàng)建jasperRecport對象,然后進(jìn)行填充,接下來就是export了。
Export操作產(chǎn)生創(chuàng)建一個用于圖像export的graphics2dExporter對象,然后從bufferedImage中取出g,接著將g,jasperPrint以及其他參數(shù)設(shè)置到exporter上,調(diào)用exportReport進(jìn)行導(dǎo)出,最后釋放g,使之生成圖像。
同時,從上可以看出,要創(chuàng)建一個指定大小的bufferedImage,以便與jasper的大小相一致,幸好japserPrint有一個取自己width和height的方法,我們直接創(chuàng)建一個和jasperPrint一樣大小的圖像就可以了。而原代碼中,創(chuàng)建的圖像大小是原大小的4倍,這是為了讓圖像盡量大一些,這樣進(jìn)行圖像識別時,能夠進(jìn)行有效地識別(比如識別圖像中的條形碼時,如果圖像太小,間隔不夠,是讀取不了的)。當(dāng)然圖像大小變大之后,需要調(diào)整生成時間的比例大小,通過為JRGraphics2DExporterParameter.ZOOM_RATIO設(shè)置一個float比例值(和圖像比例一致),這樣就可以在生成時生成相應(yīng)比例的圖像了(而且生成的圖像不是直接在原有大小的基礎(chǔ)之上進(jìn)行縮放,而是像矢量圖一樣按精確像素進(jìn)行比例重繪)。
我發(fā)現(xiàn)自己在網(wǎng)上找答案的時候遠(yuǎn)遠(yuǎn)多于去自己思考的時間,而且網(wǎng)上的許多東西都是重復(fù)的,想找到需要的信息還真困難。遇到問題時,如果自己想想能不能很好的解決,為什么非得在網(wǎng)上找呢。