报表导出Excel 二 :将业务报表数据写入特定Excel模板

本文介绍了一种报表导出为Excel的方法,包括定义报表模板、构造数据模型和服务类,最终生成可供下载的Excel文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    按照上篇博客《报表导出Excel 一 :根据业务需求设计Excel导出模板》,已经做好了报表模板,接下来简单串一下我们用到的具体service类。

    首先是,单元格cell对应的实体对象ReplaceItem, d通过这个实体类,可以具体定义每一个cell。
public class ReplaceItem {
    private int rowspan;// Excel单元格行
    private int colspan;// Excel单元格列
    private String backgroundColor;//背景色
    private String key;//变量名
    private String value;//文本值

    public ReplaceItem() {
    }
    public ReplaceItem(String key, String value) {
        this.key = key;
        this.value = value;
    }
    public int getRowspan() {
        return rowspan;
    }
    public void setRowspan(int rowspan) {
        this.rowspan = rowspan;
    }
    public int getColspan() {
        return colspan;
    }
    public void setColspan(int colspan) {
        this.colspan = colspan;
    }
    public String getBackgroundColor() {
        return backgroundColor;
    }
    public void setBackgroundColor(String backgroundColor) {
        this.backgroundColor = backgroundColor;
    }
    public String getKey() {
        return key;
    }
    public void setKey(String key) {
        this.key = key;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
}


    下面是主要的写excel的service,genExcelReport方法会根据传入的queryMap生成一个文件流到response中。
public static void genExcelReport(OutputStream os, Map<String, String> queryMap, String plantId, String localeName ,String userId) throws Exception {
        List<ReplaceItem[]> datas = new ArrayList<ReplaceItem[]>();
        String reportType = queryMap.get("reportType");
        if ("DL1".equalsIgnoreCase(reportType)) {//DL1 管理程序列表清单
            queryMap.put(MetadataConstants.NUCLEAR_STATUS, "Available");
            managementProcedureStatementExport(os, queryMap, reportType, plantId);
        }
}


     这里要根据具体业务,来将查询到的数据组合成ReplaceItemList。
private static void managementProcedureStatementExport(OutputStream os, Map<String, String> queryMap,String reportType , String plantId){
      List<ReplaceItem[]> datas = new ArrayList<ReplaceItem[]>();

      //下面是查询FileNet CE 中文档数据,Excel中数据来源于DocumentList
      String pattern = "yyyy-mm-dd";
      String startNuclearYear = queryMap.get("startNuclearYear");
      String endNuclearYear = queryMap.get("endNuclearYear");
      String bizCode = "ManageProcess";
      String osName = BizCodeConstants.getObjectNameByBizCode(bizCode);
      String whereClause = "",propertyCondition = "",statusCondition = "",timeCondition="";
      String symbolicClassName = "P"+plantId+"_ManagementProcedure";
        propertyCondition = SqlBuildCommonService.addCondition(propertyCondition, true, MetadataConstants.RECORD_CODE, true, queryMap);
        propertyCondition = SqlBuildCommonService.addCondition(propertyCondition,true,MetadataConstants.NUCLEAR_DOMAIN, true, queryMap);
        propertyCondition = SqlBuildCommonService.addCondition(propertyCondition,true,MetadataConstants.RECORD_CHINESE_TITLE, true, queryMap);
        propertyCondition = SqlBuildCommonService.addCondition(propertyCondition,true,MetadataConstants.CREATED_UNIT, true, queryMap);
        statusCondition = SqlBuildCommonService.addCondition(statusCondition, true, MetadataConstants.NUCLEAR_STATUS,true, queryMap);

        timeCondition = SqlBuildCommonService.addTimeCondition(timeCondition, MetadataConstants.NUCLEAR_YEAR,
                        queryMap.get("startNuclearYear"), queryMap.get("endNuclearYear"));
       
       
        whereClause = SqlBuildCommonService.addWhereClause(whereClause, propertyCondition);
        whereClause = SqlBuildCommonService.addWhereClause(whereClause, statusCondition);
        whereClause = SqlBuildCommonService.addWhereClause(whereClause, timeCondition);
      List<Document> docList = P8DocumentDao.searchForDocuments(ObjectStoreHelper.getObjectStore(osName), symbolicClassName, true, whereClause);             
        ReplaceItem vo = new ReplaceItem();
        vo.setKey("reportDate");
        Date startDate = DateFormatUtils.parseDate(startNuclearYear, pattern);
        Date endDate = DateFormatUtils.parseDate(endNuclearYear, pattern);
        vo.setValue("发布时间:"+new SimpleDateFormat("yyyy年MM月dd日").format(startDate)+"-"+
                  new SimpleDateFormat("yyyy年MM月dd日").format(endDate));
        ReplaceItem[] reportDateArr = {vo};
        datas.add(reportDateArr);//数组第一行必须要放报表日期,切记!!!
        for (Document doc : docList) {
            BaseDocumentMapper baseDocMapper = new BaseDocumentMapper();
            BaseDocument baseDoc = baseDocMapper.map(doc);
            
            ReplaceItem[] arr = new ReplaceItem[12];
            ReplaceItem vo1 = new ReplaceItem();
            vo1.setKey("RecordCode");
            vo1.setValue(baseDoc.getProperties().get(MetadataConstants.RECORD_CODE).toString());
            ReplaceItem vo2 = new ReplaceItem();
            vo2.setKey("RecordChineseTitle");
            vo2.setValue(baseDoc.getProperties().get(MetadataConstants.RECORD_CHINESE_TITLE).toString());
            ReplaceItem vo3 = new ReplaceItem();
            vo3.setKey("NuclearVersion/NuclearRevision");
            vo3.setValue(baseDoc.getProperties().get(MetadataConstants.NUCLEAR_VERSION)+"/"+
                        baseDoc.getProperties().get(MetadataConstants.NUCLEAR_REVISION));
            ReplaceItem vo4 = new ReplaceItem();
            vo4.setKey("NuclearDomain");
            vo4.setValue(baseDoc.getProperties().get(MetadataConstants.NUCLEAR_DOMAIN).toString());
            ReplaceItem vo5 = new ReplaceItem();
            vo5.setKey("CreatedUnit");
            vo5.setValue(baseDoc.getProperties().get(MetadataConstants.CREATED_UNIT).toString());
            ReplaceItem vo6 = new ReplaceItem();
            vo6.setKey("NuclearStatus");
            vo6.setValue(baseDoc.getProperties().get(MetadataConstants.NUCLEAR_STATUS).toString());
            ReplaceItem vo7 = new ReplaceItem();
            vo7.setKey("NuclearCreator");
            vo7.setValue(baseDoc.getProperties().get(MetadataConstants.NUCLEAR_CREATOR).toString());
            ReplaceItem vo8 = new ReplaceItem();
            vo8.setKey("Checker");
            vo8.setValue(baseDoc.getProperties().get(MetadataConstants.CHECKER).toString());
            ReplaceItem vo9 = new ReplaceItem();
            vo9.setKey("Examiner");
            vo9.setValue(baseDoc.getProperties().get(MetadataConstants.EXAMINER).toString());
            ReplaceItem vo10 = new ReplaceItem();
            vo10.setKey("Approver");
            vo10.setValue(baseDoc.getProperties().get(MetadataConstants.APPROVER).toString());
            ReplaceItem vo11 = new ReplaceItem();
            vo11.setKey("NuclearYear");
            vo11.setValue(baseDoc.getProperties().get(MetadataConstants.NUCLEAR_YEAR).toString());
            ReplaceItem vo12 = new ReplaceItem();
            vo12.setKey("NuclearAnnotation");
            vo12.setValue(baseDoc.getProperties().get(MetadataConstants.NUCLEAR_ANNOTATION).toString());
            arr[0] = vo1; arr[1] = vo2; arr[2] = vo3; arr[3] = vo4; arr[4] = vo5; arr[5] = vo6;
            arr[6] = vo7; arr[7] = vo8; arr[8] = vo9; arr[9] = vo10; arr[10] = vo11; arr[11] = vo12;
            datas.add(arr);
        }
        JexcelFiles.excelReportGenerator(os, datas, reportType, 5);
}


public static boolean excelReportGenerator(OutputStream os, List<ReplaceItem[]> datas, String sheetName, intdataRowNum) {
        boolean bool = true;
        if (datas == null) {
            return false;
        }
        String sourceFilePath = Thread.currentThread().getContextClassLoader().getResource("").getPath() + "conf"
                + File.separator + "template" + File.separator + "report_template_v1.5.xls";
        try {
            POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(sourceFilePath));
            HSSFWorkbook wb = new HSSFWorkbook(fs);
            HSSFSheet sheet = null;
            int activeSheet = 0;
            for (int i = 0; i < wb.getNumberOfSheets(); i++) {//找到模板正确的sheet页
                sheet = wb.getSheetAt(i);
                if (sheet.getSheetName() != null && sheet.getSheetName().startsWith(sheetName)) {//入库信息统计表
                    activeSheet = i;
                    break;
                }
            }
            //wb.setActiveSheet(activeSheet);
            for (int i = wb.getNumberOfSheets() - 1; i >= 0 ; i--) {//裁剪多余的sheet页
                if (i != 0 && i != activeSheet) {
                    wb.removeSheetAt(i);
                }
            }
            //1、填充报表输出日期
            Row row = sheet.getRow(3);
            if (datas.get(0) != null && datas.get(0)[0] != null) {
                for (int i = 0; i < row.getLastCellNum(); i++) {
                    Cell cell = row.getCell(i);
                    String name = cell.getStringCellValue();
                    ReplaceItem data = datas.get(0)[0];//这里规定第一行为报表输出日期
                    if (name != null && name.indexOf("$" + data.getKey()) != -1) {
                        cell.setCellValue(name.replaceAll("\\$" + data.getKey(), data.getValue()  == null ? "" : data.getValue()));
                        break;
                    }
                }
                datas = datas.subList(1, datas.size());//使用完毕后,抛弃第一行
            }

            Map<Integer, String> relMap = new HashMap<Integer, String>();//列数与变量的对应关系
            int startRow = dataRowNum, startCol = 0;
            HSSFCellStyle tableStyle = NFExcelStyle.getTableRow(wb, "");
            row = sheet.getRow(startRow);
            //2、填充数据行中的第一行,并且找到列数与变量的对应关系
            for (int i = 0; i < row.getLastCellNum(); i++) {
                sheet.autoSizeColumn(i, true);//表格内容自适应
                Cell cell = row.getCell(i);
                if(cell == null) continue;
                String name = cell.getStringCellValue();
                for (int j = 0;  j < datas.size(); j++) {
                    ReplaceItem[] data = datas.get(j);
                    for (int k = 0; k < data.length; k++) {
                        if (name != null && name.equals("$" + data[k].getKey())) {
                            relMap.put(startCol + data[k].getColspan(), data[k].getKey());
                            NFExcelStyle.createMergedCell(wb, sheet, startRow, startRow + data[k].getRowspan(),
                                    startCol, startCol + data[k].getColspan(), (i == 0), tableStyle,
                                    (data[k].getValue() == null || "null".equals(data[k].getValue())) ? "" : data[k].getValue());
                            break;
                        }
                    }
                    startCol++;
                    break;
                }
            }
            Iterator it= relMap.keySet().iterator();
            StringBuffer excelVar = new StringBuffer();
            while(it.hasNext()){
                excelVar.append(",").append(relMap.get(it.next()));
            }
            System.out.println("Excel $Var  List +++++++++++++++++++     "+ excelVar.toString() + "         +++++++++++++++++++Excel $Var  List");
            startRow++;
            //3、开始后面数据行内容填充
            for (int i = 1; i < datas.size(); i++) {
                ReplaceItem[] rowData = datas.get(i);
                for (int j = 0; j < rowData.length; j++) {
                    startCol = j;
                    for (int k = 0; k < rowData.length; k++) {
                        if (relMap.get(j).equals(rowData[k].getKey())) {
                            System.out.println("key:"+rowData[k].getKey()+"    value:"+rowData[k].getValue());
                            long d = new Date().getTime();
                            NFExcelStyle.createMergedCell(wb, sheet, startRow, startRow + rowData[k].getRowspan(),
                                    startCol, startCol + rowData[k].getColspan(), (j == 0), tableStyle,
                                    (rowData[k].getValue() == null || "null".equals(rowData[k].getValue()) ) ? "" : rowData[k].getValue());
                            long d2 = new Date().getTime();
                            System.out.println("执行时间:"+(d2-d));
                            break;
                        }
                    }
                }
                startRow++;
            }
            // 输出流
            wb.write(os);
        } catch (Exception e) {
            bool = false;
            e.printStackTrace();
        }
        return bool;
}


    基本的报表导出excel的功能点都满足了,有数据、有模板,然后构造一个数据写入excel的桥梁,最后把excel类型文件流输出到response中,就能在页面上弹出“Excel 下载提示“了。



易客报表(ExcelReport)运行在Java环境,采用Excel的习惯来制作动态报表,易学易用,在查询、统计、分析以及软件开发领域有广泛的应用价值。可以实现各类复杂报表,提供丰富的图表、方便的打印功。同时提供填报功能,只要按Excel的习惯制作好模板,发布到网上就可以用网页进行填报。 易客报表功能强大: 1. 可制作各类报表。易客报表支持多数据源,能够根据一定的规则把不同来源的数据拼装成想要的报表样式和结果。对于固定式报表,易客报表在可以为每个单元格定义取数规则的基础上,提供了导航行和导航列功能,可以为每行、每列定义通用规则;对于动态格式报表,易客报表能够让横向动态、纵向动态,并且可以让横向和纵向用动态树的方式展示;对于图表报表,易客报表支持多种图表格式,支持仪表盘。从根本看,易客报表是把业务规则定义在了报表模板中,如果业务变化则仅需更改报表设计就可以了,这有利于应对业务规则的变化,也有利于减少技术支持和维护工作负担。 2. 可制作各类填报。支持清单、卡片、主从等填报样式。并且支持分页填报,这对大量数据的填报是很有必要的。 3. 强大的参数功能。支持各类控件样式的报表参数。在参数窗体中,不为参数值录入数据则相当于让参数不起作用,使报表非常灵活。 4. 优质的Web体验。易客报表与快乐门户绑定,提供美观、便捷的Web操作体验。 5. 权限管理。提供类似Windows NT那样的权限机制,安全有效。这得益于易客报表绑定的快乐服务器,那是一种科学的知识库体系。 6. 分布式管理。当易客报表布置到异地多个环境的时候,如何统一、便捷地管理和维护各个环境中的报表模板?易客报表支持分布式管理。您还可以免费注册淘表网帐号,把报表模板同步到淘表网,您的报表模板将不再容易丢失和难于管理。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是一道光_

1分也是爱,鼓励鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值