天天看点

ireport+jasperreport 直接输出到打印机 普通报表 交叉报表

       项目中要用到针式打印机票据打印,本来是使用java printable 通过 Graphic2D输出到图形化方式打印的,运行了一段时间客户对版面个性需要比较多,用输出图形的方式调整太麻烦,而且Graphic2D画表格真的很麻烦,所以后来选择用ireport来定制版面,通过jasperreport api直接输送到打印机上。

       目前针式打印几比较通用的纸张是9.5*5.5英寸的,根据不同客户的需求,我们定制了2种版面,因为我们是做服装行业的,一类客户是不管理尺码的,列数比较少纵向打印比较省纸张,另一种是管颜色尺码,以动态尺码为表头,需要用到交叉报表。

      数据是从客户端通过socket发送到我的程序上的,所以需要用到javabean数据源。

      首先第一步创建测试数据源,创建一个javabean类用于承载数据,创建一个工厂类用于提供数据。

public class JasperDatasourceFactory {

    public static Collection createBeanCollection1() throws Exception{

          List list_1=new ArrayList();

          //填充list_1

          return list_1;

    }

}

在ireport添加项目的classpath,工具-选项-classpath,添加完之后需要重启ireport,不然找不到。

ireport+jasperreport 直接输出到打印机 普通报表 交叉报表

创建一个ireport空模板,设置报表属性width=369 height=684   及上面提及纸张的纵向模式

创建javabean数据源,并将数据源设为默认数据源:

ireport+jasperreport 直接输出到打印机 普通报表 交叉报表

3.导入数据源字段:

右键导航栏里的根节点,点击edit query,进入后切换到javabean datasource,填写javabean类路径,点击read attributes,把要统计的自动天下到下方的列表中

ireport+jasperreport 直接输出到打印机 普通报表 交叉报表

添加完后,在导航栏的fields节点下就显示这些导入的这些字段,把这些字段一次拖到报表版面的detail 区域,基本的报表就完成了直接可以点击预览,下面是我完整的报表版面:

ireport+jasperreport 直接输出到打印机 普通报表 交叉报表

上面的的布局是通过精心排布完成的,下面有几点要说明的:

1.报表版面上各个栏生成报表如何展现:

Title:故名思议标题栏,如果有多页只在第一页显示

Page Header:  页头,每一页都显示

Column Header:顾名思义就是表头,每一页重复显示

Detail:列表区

PageFooter:页尾,置底显示,每一页显示

summary:合计栏,更在最后一页表格的后面

2.添加合计

   列表的合计栏需要放到summary区域,虽然和列表身首异处,但是生成报表的时候绝对是连载一起的。

   在导航栏的Variables中添加一个Variables,并在属性对话框里设置统计参数,将创建好的Variables拖到summary栏:

ireport+jasperreport 直接输出到打印机 普通报表 交叉报表

3.如果添加parameter,page header、page footer、summary中有一些报表描述性的内容,通过参数传进来。

   在导航栏的parameters节点右键点击添加Parameters,添加好后在下面重命名成你要的参数名,并把它拖拽到报表页面上

4.设置添加边框

   中国人总是喜欢条条框框,所以中国式报表大多都有表格,所以需要给表格设置边框。

   全选column header、detail、summary中需要加边框的控件,在属性栏中设置style属性为table_td:

ireport+jasperreport 直接输出到打印机 普通报表 交叉报表

5.使用表达式

    如批次下方这里,如果是销售单显示"客户",如果是调拨单显示"调出地",在此处添加一个text field 右键点edit expression,填写如下格式:

    $P{type}.equals( "21")?"客户:":($P{type}.equals( "22")?"供应商:":"调出店:")

6.设置高度自适应及控件自动偏移,如accountinfo这个参数,如果内容多发生换行,如果不设置自动拉升内容会被遮掉,如果设置了自动拉伸,下面的内容会被遮挡。

   选择需要自动拉伸和自动偏移的控件,设置属性:

stretch type:relative to tallest height   设置自动拉伸

position type: float   设置自动偏移,如果上面一行控件拉伸,下面的控件自动下移。

ireport+jasperreport 直接输出到打印机 普通报表 交叉报表

如果同一行有多个控件,需要设置组,否则可能有因为偏移导致对不起的情况,归组操作方式,选择这一行所有控件,右键点击group selected elements。

至此,第一类报表的模板已完成,可以点击预览展现,不过用参数的地方都显示为null。

打印效果:

ireport+jasperreport 直接输出到打印机 普通报表 交叉报表

下面是如何使用jasperreport直接输出到打印机上:

        String sourceFileName = "/jasper/" + paper.getModefile();

        Collection datasource = printer.getList();//这里是我获取数据集的地方

        Map parameters = printer.getParam();//报表里要用到parameters,存放在map里

        JRBeanCollectionDataSource beanColDataSource =

                new JRBeanCollectionDataSource(datasource);

         InputStream reportStream=null;

        try {

            //报表变异jasper文件的文件流

            reportStream=new FileInputStream(URLDecoder.decode(AppUtil.rootPath+sourceFileName, "UTF-8"));

            JasperPrint jasperPrint = JasperFillManager.fillReport(reportStream, parameters, beanColDataSource);

            //设置成打印横向

            jasperPrint.setOrientation(OrientationEnum.LANDSCAPE);

           //获取打印服务

            PrintService printService = null;

            if (printerName.equals("default")) {

                printService = PrintServiceLookup.lookupDefaultPrintService();

            } else {

                PrintService[] printlist = PrintServiceLookup.lookupPrintServices(null, null);

                //printService=printlist[0];

                for (int i = 0; i < printlist.length; i++) {

                    if (printerName.equals(printlist[i].getName())) {

                        printService = printlist[i];

                        break;

                    }

                }

            }

            JRAbstractExporter je = new MyJRPrintServiceExporter();//自带的JRPrintServiceExporter对自定义打印纸张有点瑕疵,原因不是很清楚,我做了继承并修改了JRPrintServiceExporter一段代码就可以了,稍后贴出代码

           //设置打印内容

            je.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);

            //设置指定打印机  

            je.setParameter(JRPrintServiceExporterParameter.PRINT_SERVICE, printService);

            //有些个性化的参数,我在我的设置类里再设置

            printer.setFormat(jasperPrint, je);

            je.exportReport();

       上面提及的JRPrintServiceExporter中,需要把

                   printerJob.setPrintable(this, pageFormat);

       替换成

                    pageFormat.setPaper(paper);

                    Book pBook = new Book();

                    pBook.append(this, pageFormat,jasperPrint.getPages().size());

                    printerJob.setPageable(pBook);

     接下来讲一下交叉报表的制作方法:

     交叉报表是对一组原始数据进行多维度的统计,类似Office的数据透视表,例如如下的数据源:

      款号  名称     颜色     尺码   数量   单价  金额

      A         马甲    红          S          2       200  400

      A         马甲    红          M          2      200   400

      B         皮衣    黑          S          3       500  1500

      B         皮衣     黑         M          4       500   2000

      通过交叉报表输出如下格式的报表

                                              尺码

      款号  名称   颜色       S          M   总数   单价   总金额

      A        马甲   红          2            2    4      200     800

      B        皮衣    黑        3            4     7      500     3500

     合计                            5            6     11    700    4300

      ireport中

    首先第一步,按上述方式创建数据源,并导入查询属性(字段)到fields中。

     第二步从组件面板中拖拽crosstab到summary栏,注意必须是summary栏。在制作交叉报表的时候column header、column footer 、detail栏没有用处可以隐去,其他栏还是按照上面介绍ireport band一样的显示方式。

     接前所述,将crosstab拖拽到summary band的时候,会弹出交叉报表创建向导:

       1.选择dataset 为 main report dataset

       2.选择两个行分组