使用JasperReport输出image图像
最近公司新项目上有一个新的需要,即在原来用jasper打印出来的文档上面,加上一个可以进行识别的东西(暂定为条形码),然后对这个文档的扫描件进行识别。初步确定就是修改原有的jasper资源文件,并在打印方法中加入一个对条形码的field引用,这样来完成在文档上打印条形码的需求。
但后面这一需要进一步修正,因为要将扫描件保存入数据库中,这时就想到如果不通过扫描设备,而直接将jasper在客户端调出打印的时候,由服务器端生成一个jasper图像,再将这个图像直接入库。这样就避免了二次扫描的麻烦。
在网上google了一下关于jasperReport的应用,发现大部分都是讲如何将jasper导入一个html或pdf进行打印的例子,并没有直接将jasperReport打印生成一个图像的示例。包括jaspe自带的demo里面,也没有相应的例子,决定自己看看相应的api,找一个可以运用的东西。
产生想到的是jasper自带的ImageServlet这个类,认为可以从这个类方法中找到一些可以参考的东西。可惜将代码粗略看一道,就失望了。这个类不是将一个jasper输出一个图像文件,而是输出一个jasper文件中指定图像名称中的图像信息。也就是说,这个类根本不能将一个jasper完整输出成一个图像的byte[]数组。看完这个类,我还真不知道这个类有什么样,至少现在我不看好这个类。
接到就找export包中的相应类,看能否找到一个根图像有关的exporter,最后找到这样一个类:JRGraphics2DExporter.java,从文档可以看出,它可以完整的将一个jasper文档输出到一个graphics对象中,而不像其他的exporter只是近似的模拟。但是这个文档同时也说明,它只是输出到graphics对象,而不是输出到一个文件或字节流中。当然这不是问题,我们可以创建一个可以产生graphics的对象(比如说bufferedimage),然后用g进行export,当然最后的信息就保存在拥有g的对象上了。接下来的操作就简单了。
如下代码所示:
Map parameters = new HashMap();
JasperPrint jasperPrint =
JasperFillManager.fillReport(
(JasperReport) JRLoader.loadObject(new File("d:/injuryPresume.jasper")),//jasper对象
parameters,//参数列表
new JREmptyDataSource()//数据源信息
);
JRGraphics2DExporter exporter = new JRGraphics2DExporter();//创建graphics输出器
//创建一个影像对象
BufferedImage bufferedImage = new BufferedImage(jasperPrint.getPageWidth() * 4, jasperPrint.getPageHeight() * 4, BufferedImage.TYPE_INT_RGB);
//取graphics
Graphics2D g = (Graphics2D) bufferedImage.getGraphics();
//设置相应参数信息
exporter.setParameter(JRGraphics2DExporterParameter.GRAPHICS_2D, g);
exporter.setParameter(JRGraphics2DExporterParameter.ZOOM_RATIO, Float.valueOf(4));
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.exportReport();
g.dispose();//释放资源信息
//这里的bufferedImage就是最终的影像图像信息,可以通过这个对象导入到cm中了.
ImageIO.write(bufferedImage, "JPEG", new File("d:/aa.jpg"));
由上可以看出,和普通的htmlexporter一样,产生创建jasperRecport对象,然后进行填充,接下来就是export了。
Export操作产生创建一个用于图像export的graphics2dExporter对象,然后从bufferedImage中取出g,接着将g,jasperPrint以及其他参数设置到exporter上,调用exportReport进行导出,最后释放g,使之生成图像。
同时,从上可以看出,要创建一个指定大小的bufferedImage,以便与jasper的大小相一致,幸好japserPrint有一个取自己width和height的方法,我们直接创建一个和jasperPrint一样大小的图像就可以了。而原代码中,创建的图像大小是原大小的4倍,这是为了让图像尽量大一些,这样进行图像识别时,能够进行有效地识别(比如识别图像中的条形码时,如果图像太小,间隔不够,是读取不了的)。当然图像大小变大之后,需要调整生成时间的比例大小,通过为JRGraphics2DExporterParameter.ZOOM_RATIO设置一个float比例值(和图像比例一致),这样就可以在生成时生成相应比例的图像了(而且生成的图像不是直接在原有大小的基础之上进行缩放,而是像矢量图一样按精确像素进行比例重绘)。
我发现自己在网上找答案的时候远远多于去自己思考的时间,而且网上的许多东西都是重复的,想找到需要的信息还真困难。遇到问题时,如果自己想想能不能很好的解决,为什么非得在网上找呢。
上一篇: 构造器
下一篇: java 实现一个简单的猜字符小游戏