POI导出

1.基本功能 1. 基本功能

导出功能使用的是是EC的POI导出功能,导出需要配置对应的模板文件。对应的excel模板平台默认生成的路径是WebContent路径。但是在实际使用中需要对excel模板文件进行调整。
– POI模板读取策略,从Tomcat目录中读取,一般是开发期使用或者是单系统引用。
glpaas.poi.readTemplteStrategy=default
– POI模板读取策略,从Jar中读取,一般是SpringBoot项目使用。如果是jar需要确保对应的excel文件可以打包到jar中,可以手工拷贝到resource下或者是通过pom文件配置打包时自动拷贝到jar中。
glpaas.poi.readTemplteStrategy=jar
– POI模板读取策略,从Ftp中读取,单系统、SpringBoot项目都可以使用。
glpaas.poi.readTemplteStrategy=ftp

若springboot项目打成jar包后xlsx打开显示已损坏,需要添加pom配置:
<resource>
<filtering>false</filtering>
<directory>src\resources</directory>
<includes>
<include>/*.ftl</include>
</includes>
<excludes>
<exclude>deploy/
</exclude>
</excludes>
</resource>

1.1.分组表格及分组表格的导出 1.1. 分组表格及分组表格的导出

注意点:文件名要跟POI配置里面的导出文件名一致;页面上有显示的列在模板里面都要添加进去(普表格的导出模板则不需要全部添加);配置完生成代码拷到业务系统预览效果

例子主要使用的是单表,布局是上下结构,主要功能点是展示分组表格和分组表格的导出。
TestCase315-1 TestCase315-2

1.2.下拉过滤导入、导出 1.2. 下拉过滤导入、导出

例子主要展示表格的导入导出功能,导入可根据字段的过滤筛选再导出过滤出的数据。
tab38

1.3. 按表格布局导出Excel文件 1.3. 按表格布局导出Excel文件

此功能的场景是根据界面上表格的布局导出Excel文件,表格显示几列就导出几列。
1.4.重置后刷新当前数据

1.4. 重置后刷新当前数据

查询之后,点击重置,再点击导出,导出内容为之前查询的结果。
1.5.导出excel名称配置

1.5. 导出excel名称配置

1.5.1.导出excel、导出EXCEL名称页面按照标题+年月日+时间(秒)命名

1.5.2.查询之后,勾选几条记录,导出excel,导出的文件名根据配置定义生成。

1
2
1.6.自定义导出工资条(没有使用POI)

1.6. 自定义导出工资条(没有使用POI)

1.6.1.场景描述

在付款申请页面勾选付款状态是已付款的记录点击【导出工资单】按钮导出数据。如果勾选的记录里面包含未付款的则提示“存在确认付款数据,无法导出!”这个导出的例子没有使用云平台的POI配置,用的是导出的一个工具类,工具类的代码在本文后面有贴出来。

1.6.2.效果图如下:

QQ截图20180904135907
1.7.分组表格导出配置说明

1.7. 分组表格导出配置说明

1.8.单表导出

1.8. 单表导出

此功能的场景是页面表格上有导出按钮,点导出按钮导出当前显示的数据或者导出当前选中的数据,下拉控件、地区控件可转换。
1.9.主从表导出

1.9. 主从表导出

主从表的导出是先把主表和从表写成一个视图(自定义SQL语句),然后用这个SQL语句创建一个业务对象,导出的时候取这个业务对象里面的数据。

2.配置方法 2. 配置方法

  • 导入导出的模板路径,如果是单系统,模板放在WebContent目录下。例如ttt项目:D:\ttt\WebContent\uploadFiles\local;
    如果是分布式系统,模板要放在resource下,例如ttt分布式项目:E:\ttt_micro_ec3\ttt-bas\ttt-bas-business\src\resources\uploadFiles\local。
  • 2.1.分组表格及分组表格的导出

    2.1. 分组表格及分组表格的导出

    配置

    1.对象建模–业务对象–业务对象管理:编辑业务对象,点击【可视化布局】按钮;【表格类型】设置HandsontableGroup
    TestCase315-4
    2对象建模–基础数据–POI配置管理,配置对应业务对象的导出数据。
    TestCase315-7
    TestCase315-8
    3.POI配置完成后,点击“同步到目标数据库”按钮。
    4.在业务对象的管理页按钮页面中把导出按钮配置进去(导出方法默认有的,不需要再新增方法)。
    TestCase315-9
    5.制作导出的模板文件。
    TestCase315-10

    2.2.下拉过滤导入、导出 2.2. 下拉过滤导入、导出

    配置

    1.对象建模–业务对象–业务对象管理:编辑业务对象,点击方法定义Tab 点击【编辑】按钮
    tab39
    2.在业务对象–管理页按钮中,添加导入导出方法按钮
    tab40

    3.在基础数据–poi配置管理中,配置对应业务对象的导入导出数据。
    tab41
    tab43
    tab42
    4.配置完成后,点击“同步到目标数据库”。

    5.在规则建模–策略表管理中,配置导入的规则数据
    tab44
    6.提交,同步到目标数据库。
    7.新增模版文件,并放至对应的项目路径下,该路径与poi配置中的模版文件路径一致。
    8.新增规则文件,并放置对应的项目路径下,该路径与策略管理中配置的规则路径保持一致。
    9.生成代码,启动项目,配置对应权限即可看到效果。

    代码

    例子路径:com\gillion\sample\test\bizrule\testCase313ImportExcel.drl

    import java.util.*;
    import com.gillion.platform.utils.SpringContextHolder;
    import com.gillion.sample.test.domain.TestCase313;
    import com.gillion.sample.test.service.TestCase313Service;
    import java.math.BigDecimal;
    
    rule "TestCase313导入"
    
    when
        dataMap : Map()
    then
        System.out.println("开始调用规则:TestCase313ImportExcel");
        List<TestCase313> data = (List<TestCase313>)dataMap.get("dataList");
        Map paramMap = (Map)dataMap.get("paramMap");
    
        Map result = new HashMap();
        try{
                TestCase313Service TestCase313Service = (TestCase313Service) SpringContextHolder.getBean(TestCase313Service.class);
                for(int i=0; i<data.size(); i++){
                    TestCase313 s = (TestCase313)data.get(i);
                    s.setRowStatus(4);
                    TestCase313Service.save(s);
                }
                result.put("msg","导入成功");
            } catch(Exception e) {
            result.put("msg",e.getMessage());
        }
        dataMap.put("result",result);
    end
    
    

    2.3.按表格布局导出Excel文件

    2.3. 按表格布局导出Excel文件

    1.对象建模–业务对象–业务对象管理:编辑业务对象,勾选生成导出模板。
    导出01
    2.对象建模–业务对象–业务对象管理:编辑业务对象,点击【可视化布局】按钮 选择导出方法并且选中id显示出来。
    QQ截图20190311112937
    3.提交对象;提交的时候会在基础数据-poi配置中生成对应的配置数据。其中模板路径为【/uploadFiles/local/模板文件名】【/uploadFiles/local/TestExam3101Template.xlsx】
    4.POI配置中需要将配置数据【同步到目标数据库】,如果不是开发库,可以【导出配置数据】,然后将导出的脚本刷新到对应的数据库中。
    导出POI
    5.生成业务对象代码。生成的时候会生成对应的模板文件。如果不需要再次生成模板文件,可将步骤1制作模板那个选项去掉即可。

    2.4.重置后刷新当前数据

    2.4. 重置后刷新当前数据

    2.4.1. 需重新生成代码

    2.4.2.在config.properties.js文件中重置查询条件,刷新当前数据:

    1
    2.5.导出excel名称配置

    2.5. 导出excel名称配置

    2.5.1. 以上方展示效果为例,在application.properties增加一个配置exportFile.dynaFileName=@fileName_@currentDateTime.xlsx

    2.5.2. SpringBoot项目则在yml文件上增加配置exportFile,例如:

    exportFile:
        dynaFileName: @fileName_@currentDateTime.xlsx
    

    目前支持以下变量的配置:

    @fileName:取值为基础数据-POI配置管理-导入导出文件名
    @currentDateTime:当前日期时间yyyyMMddHHmmss
    @currentDate:当前时间HHmmss
    @year:年
    @month:月
    @day:日
    @hour:时
    @minute:分
    @second:秒
    

    2.6. 自定义导出工资条(没有使用POI)

    2.6. 自定义导出工资条(没有使用POI)

    2.6.1.在方法定义里面自定义一个方法,类型选择自定义JS函数。

    QQ截图20180904160349

    2.6.2.在当前业务对象+ManageCtrl.js里面写自定义js内容,代码参考如下:

    $scope.exportDetailVwBcPaymentRequest = function() {
                if($scope.vwBcPaymentRequestCheckedRows.length==0){
                    GillionMsg.alert("提示","请选择付款申请单!");
                    return;
                }
                for(var i=0; i<$scope.vwBcPaymentRequestCheckedRows.length; i++){
                    if($scope.vwBcPaymentRequestCheckedRows[i].requestStatus!="2"){
                        GillionMsg.alert("提示","存在确认付款数据,无法导出!");
                        return;
                    }
                }
                var bcPaymentRequestNos=Arrays.extract($scope.vwBcPaymentRequestCheckedRows,'requestNo').join(',');
                var  form=$("<form>");//定义一个form表单
                form.attr("style","display:none");
                form.attr("target","");
                form.attr("method","post");
                form.attr("action",$config.ctx + "/BcPaymentRequest/excelCheck");
                var requestNos=$("<input>");
                requestNos.attr("type","hidden");
                requestNos.attr("name","requestNos");
                requestNos.attr("value",bcPaymentRequestNos);
                $("body").append(form);//将表单放置在web中
                form.append(requestNos);
                form.submit();
            };
    

    2.6.3.自定义控制器代码参考如下:

     @RequestMapping(value="BcPaymentRequest/excelCheck",method = RequestMethod.POST)
        @ResponseBody
        public void excelCheck( HttpServletRequest request, HttpServletResponse response){
            String requestNos =  request.getParameter("requestNos");
            String[] bcPaymentRequestNo = requestNos.split(",");
            VwPaymentRequestDetailExample example = VwPaymentRequestDetailExample.create();
            example.createCriteria().andRequestNoIn(Arrays.asList(bcPaymentRequestNo));
            List<VwPaymentRequestDetail> vwPaymentRequestDetails = vwPaymentRequestDetailService.selectByExample(example);
            bcPaymentRequestExtService.exportExcle(vwPaymentRequestDetails,response);
        }
    

    2.6.4.自定义接口类代码参考如下:

     /**
         * 司机工资单导出
         * @param vwPaymentRequestDetails
         * @param response
         */
        public void exportExcle(List<VwPaymentRequestDetail> vwPaymentRequestDetails, HttpServletResponse response);
    

    2.6.5.自定义实现类代码参考如下:

    @Override
        public void exportExcle(List<VwPaymentRequestDetail> vwPaymentRequestDetails, HttpServletResponse response) {
            Map<String,String> map = new LinkedHashMap<String,String>();
            map.put("requestNo","申请单号");
            map.put("paytime","付款日期");
            map.put("transportMonth","运费所属月份");
            map.put("settleCustName","司机姓名");
            map.put("phone","司机联系电话");
            map.put("accountName","账户名");
            map.put("account","账号");
            map.put("bank","银行信息");
            map.put("project","项目名称");
            map.put("inMoney","应收");
            map.put("outMoney","应付");
            ExcelUtil.downloadExcelFile("司机工资单", map, JSONArray.parseArray(JSON.toJSONString(vwPaymentRequestDetails)),response);
        }
    

    2.6.6.导出的工具类:ExcelUtil.java代码参考如下:

    package com.gillion.base.utils;
    
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.math.BigDecimal;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Iterator;
    import java.util.Map;
    
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.poi.hpsf.SummaryInformation;
    import org.apache.poi.hssf.usermodel.HSSFCell;
    import org.apache.poi.hssf.usermodel.HSSFCellStyle;
    import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
    import org.apache.poi.hssf.usermodel.HSSFComment;
    import org.apache.poi.hssf.usermodel.HSSFFont;
    import org.apache.poi.hssf.usermodel.HSSFPatriarch;
    import org.apache.poi.hssf.usermodel.HSSFRichTextString;
    import org.apache.poi.hssf.usermodel.HSSFRow;
    import org.apache.poi.hssf.usermodel.HSSFSheet;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    import org.apache.poi.ss.usermodel.CellStyle;
    import org.apache.poi.ss.usermodel.Font;
    import org.apache.poi.ss.util.CellRangeAddress;
    import org.apache.poi.xssf.streaming.SXSSFCell;
    import org.apache.poi.xssf.streaming.SXSSFRow;
    import org.apache.poi.xssf.streaming.SXSSFSheet;
    import org.apache.poi.xssf.streaming.SXSSFWorkbook;
    
    import com.alibaba.fastjson.JSONArray;
    import com.alibaba.fastjson.JSONObject;
    
    /**
     * Created by zhoubin on 2017/3/7.
     */
    public class ExcelUtil {
    
        public static String NO_DEFINE = "no_define";//未定义的字段
        public static String DEFAULT_DATE_PATTERN="yyyy年MM月dd日";//默认日期格式
        public static int DEFAULT_COLOUMN_WIDTH = 17;
        /**
         * 导出Excel 97(.xls)格式 ,少量数据
         * @param title 标题行
         * @param headMap 属性-列名
         * @param jsonArray 数据集
         * @param datePattern 日期格式,null则用默认日期格式
         * @param colWidth 列宽 默认 至少17个字节
         * @param out 输出流
         */
        public static void exportExcel(String title,Map<String, String> headMap,JSONArray jsonArray,String datePattern,int colWidth, OutputStream out) {
            if(datePattern==null) datePattern = DEFAULT_DATE_PATTERN;
            // 声明一个工作薄
            HSSFWorkbook workbook = new HSSFWorkbook();
            workbook.createInformationProperties();
            workbook.getDocumentSummaryInformation().setCompany("*****公司");
            SummaryInformation si = workbook.getSummaryInformation();
            si.setAuthor("JACK");  //填加xls文件作者信息
            si.setApplicationName("导出程序"); //填加xls文件创建程序信息
            si.setLastAuthor("最后保存者信息"); //填加xls文件最后保存者信息
            si.setComments("JACK is a programmer!"); //填加xls文件作者信息
            si.setTitle("POI导出Excel"); //填加xls文件标题信息
            si.setSubject("POI导出Excel");//填加文件主题信息
            si.setCreateDateTime(new Date());
            //表头样式
            HSSFCellStyle titleStyle = workbook.createCellStyle();
            titleStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
            HSSFFont titleFont = workbook.createFont();
            titleFont.setFontHeightInPoints((short) 20);
            titleFont.setBoldweight((short) 700);
            titleStyle.setFont(titleFont);
            // 列头样式
            HSSFCellStyle headerStyle = workbook.createCellStyle();
            headerStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
            headerStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
            headerStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
            headerStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
            headerStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
            headerStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
            HSSFFont headerFont = workbook.createFont();
            headerFont.setFontHeightInPoints((short) 12);
            headerFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
            headerStyle.setFont(headerFont);
            // 单元格样式
            HSSFCellStyle cellStyle = workbook.createCellStyle();
            cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
            cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
            cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
            cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
            cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
            cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
            cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
            HSSFFont cellFont = workbook.createFont();
            cellFont.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
            cellStyle.setFont(cellFont);
            // 生成一个(带标题)表格
            HSSFSheet sheet = workbook.createSheet();
            // 声明一个画图的顶级管理器
            HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
            // 定义注释的大小和位置,详见文档
            HSSFComment comment = patriarch.createComment(new HSSFClientAnchor(0,
                    0, 0, 0, (short) 4, 2, (short) 6, 5));
            // 设置注释内容
            comment.setString(new HSSFRichTextString("可以在POI中添加注释!"));
            // 设置注释作者,当鼠标移动到单元格上是可以在状态栏中看到该内容.
            comment.setAuthor("JACK");
            //设置列宽
            int minBytes = colWidth<DEFAULT_COLOUMN_WIDTH?DEFAULT_COLOUMN_WIDTH:colWidth;//至少字节数
            int[] arrColWidth = new int[headMap.size()];
            // 产生表格标题行,以及设置列宽
            String[] properties = new String[headMap.size()];
            String[] headers = new String[headMap.size()];
            int ii = 0;
            for (Iterator<String> iter = headMap.keySet().iterator(); iter
                    .hasNext();) {
                String fieldName = iter.next();
    
                properties[ii] = fieldName;
                headers[ii] = fieldName;
    
                int bytes = fieldName.getBytes().length;
                arrColWidth[ii] =  bytes < minBytes ? minBytes : bytes;
                sheet.setColumnWidth(ii,arrColWidth[ii]*256);
                ii++;
            }
            // 遍历集合数据,产生数据行
            int rowIndex = 0;
            for (Object obj : jsonArray) {
                if(rowIndex == 65535 || rowIndex == 0){
                    if ( rowIndex != 0 ) sheet = workbook.createSheet();//如果数据超过了,则在第二页显示
    
                    HSSFRow titleRow = sheet.createRow(0);//表头 rowIndex=0
                    titleRow.createCell(0).setCellValue(title);
                    titleRow.getCell(0).setCellStyle(titleStyle);
                    sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, headMap.size() - 1));
    
                    HSSFRow headerRow = sheet.createRow(1); //列头 rowIndex =1
                    for(int i=0;i<headers.length;i++)
                    {
                        headerRow.createCell(i).setCellValue(headers[i]);
                        headerRow.getCell(i).setCellStyle(headerStyle);
    
                    }
                    rowIndex = 2;//数据内容从 rowIndex=2开始
                }
                JSONObject jo = (JSONObject) JSONObject.toJSON(obj);
                HSSFRow dataRow = sheet.createRow(rowIndex);
                for (int i = 0; i < properties.length; i++)
                {
                    HSSFCell newCell = dataRow.createCell(i);
    
                    Object o =  jo.get(properties[i]);
                    String cellValue = "";
                    if(o==null) cellValue = "";
                    else if(o instanceof Date) cellValue = new SimpleDateFormat(datePattern).format(o);
                    else cellValue = o.toString();
    
                    newCell.setCellValue(cellValue);
                    newCell.setCellStyle(cellStyle);
                }
                rowIndex++;
            }
            // 自动调整宽度
            /*for (int i = 0; i < headers.length; i++) {
                sheet.autoSizeColumn(i);
            }*/
            try {
                workbook.write(out);
                workbook.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        /**
         * 导出Excel 2007 OOXML (.xlsx)格式
         * @param title 标题行
         * @param headMap 属性-列头
         * @param jsonArray 数据集
         * @param datePattern 日期格式,传null值则默认 年月日
         * @param colWidth 列宽 默认 至少17个字节
         * @param out 输出流
         */
        public static void exportExcelX(String title,Map<String, String> headMap,JSONArray jsonArray,String datePattern,int colWidth, OutputStream out) {
            if(datePattern==null) datePattern = DEFAULT_DATE_PATTERN;
            // 声明一个工作薄
            SXSSFWorkbook workbook = new SXSSFWorkbook(1000);//缓存
            workbook.setCompressTempFiles(true);
            //表头样式
            CellStyle titleStyle = workbook.createCellStyle();
            // 设置单元格边框样式
            titleStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);     // 上边框 细边线
            titleStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);  // 下边框 细边线
            titleStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);    // 左边框 细边线
            titleStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);   // 右边框 细边线
            titleStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);    // 水平居中
            titleStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 垂直居中
            /*titleStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
            // 背景色
            titleStyle.setFillForegroundColor(HSSFColor.WHITE.index);
            titleStyle.setFillBackgroundColor(HSSFColor.YELLOW.index);
            */
            Font titleFont = workbook.createFont();
            titleFont.setFontHeightInPoints((short) 20); // 字体高度
            titleFont.setFontName("黑体"); // 字体样式
            titleStyle.setFont(titleFont);
            // 列头样式
            CellStyle headerStyle = workbook.createCellStyle();
            // headerStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
            headerStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
            headerStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
            headerStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
            headerStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
            headerStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
            headerStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 垂直居中
            Font headerFont = workbook.createFont();
            headerFont.setFontHeightInPoints((short) 15); // 字体高度
            headerFont.setFontName("黑体"); // 字体样式
            headerStyle.setFont(headerFont);
            // 单元格样式
            CellStyle cellStyle = workbook.createCellStyle();
           /* cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);*/
            cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
            cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
            cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
            cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
            cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
            cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
            // 设置字体样式
            Font cellFont = workbook.createFont();
            titleFont.setFontHeightInPoints((short) 15); // 字体高度
            titleFont.setFontName("黑体"); // 字体样式
            cellStyle.setFont(cellFont);
            // 生成一个(带标题)表格
            SXSSFSheet sheet = (SXSSFSheet) workbook.createSheet();
            //设置列宽
            int minBytes = colWidth<DEFAULT_COLOUMN_WIDTH?DEFAULT_COLOUMN_WIDTH:colWidth;//至少字节数
            int[] arrColWidth = new int[headMap.size()];
            // 产生表格标题行,以及设置列宽
            String[] properties = new String[headMap.size()];
            String[] headers = new String[headMap.size()];
            int ii = 0;
            for (Iterator<String> iter = headMap.keySet().iterator(); iter
                    .hasNext();) {
                String fieldName = iter.next();
    
                properties[ii] = fieldName;
                headers[ii] = headMap.get(fieldName);
    
                int bytes = fieldName.getBytes().length;
                arrColWidth[ii] =  bytes < minBytes ? minBytes : bytes;
                sheet.setColumnWidth(ii,arrColWidth[ii]*256);
                ii++;
            }
            // 遍历集合数据,产生数据行
            int rowIndex = 0;
            for (Object obj : jsonArray) {
                if(rowIndex == 65535 || rowIndex == 0){
                    if ( rowIndex != 0 ) sheet = (SXSSFSheet) workbook.createSheet();//如果数据超过了,则在第二页显示
    
                    SXSSFRow titleRow = (SXSSFRow) sheet.createRow(0);//表头 rowIndex=0
                    titleRow.createCell(0).setCellValue(title);
                    titleRow.getCell(0).setCellStyle(titleStyle);
                    sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, headMap.size() - 1));
    
                    SXSSFRow headerRow = (SXSSFRow) sheet.createRow(1); //列头 rowIndex =1
                    for(int i=0;i<headers.length;i++)
                    {
                        headerRow.createCell(i).setCellValue(headers[i]);
                        headerRow.getCell(i).setCellStyle(headerStyle);
    
                    }
                    rowIndex = 2;//数据内容从 rowIndex=2开始
                }
                JSONObject jo = (JSONObject) JSONObject.toJSON(obj);
                SXSSFRow dataRow = (SXSSFRow) sheet.createRow(rowIndex);
                for (int i = 0; i < properties.length; i++)
                {
                    SXSSFCell newCell = (SXSSFCell) dataRow.createCell(i);
    
                    Object o =  jo.get(properties[i]);
                    String cellValue = "";
                    if(o==null) cellValue = "";
                    else if(o instanceof Date) cellValue = new SimpleDateFormat(datePattern).format(o);
                    else if(o instanceof Float || o instanceof Double)
                        cellValue= new BigDecimal(o.toString()).setScale(2,BigDecimal.ROUND_HALF_UP).toString();
                    else cellValue = o.toString();
    
                    newCell.setCellValue(cellValue);
                    newCell.setCellStyle(cellStyle);
                }
                rowIndex++;
            }
            // 自动调整宽度
            /*for (int i = 0; i < headers.length; i++) {
                sheet.autoSizeColumn(i);
            }*/
            try {
                workbook.write(out);
                workbook.close();
                workbook.dispose();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 导出Excel 2007 OOXML (.xlsx)格式
         * @param title 标题行
         * @param headMap 属性-列头
         * @param jsonArray 数据集
         * @param datePattern 日期格式,传null值则默认 年月日
         * @param colWidth 列宽 默认 至少17个字节
         * @param out 输出流
         */
        public static void exportExcelX2(String title,Map<String, String> headMap,JSONArray jsonArray,String datePattern,int colWidth, OutputStream out) {
            if(datePattern==null) datePattern = DEFAULT_DATE_PATTERN;
            // 声明一个工作薄
            SXSSFWorkbook workbook = new SXSSFWorkbook(1000);//缓存
            workbook.setCompressTempFiles(true);
            //表头样式
            CellStyle titleStyle = workbook.createCellStyle();
            // 设置单元格边框样式
            titleStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);     // 上边框 细边线
            titleStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);  // 下边框 细边线
            titleStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);    // 左边框 细边线
            titleStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);   // 右边框 细边线
            titleStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);    // 水平居中
            titleStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 垂直居中
            /*titleStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
            // 背景色
            titleStyle.setFillForegroundColor(HSSFColor.WHITE.index);
            titleStyle.setFillBackgroundColor(HSSFColor.YELLOW.index);
            */
            Font titleFont = workbook.createFont();
            titleFont.setFontHeightInPoints((short) 20); // 字体高度
            titleFont.setFontName("黑体"); // 字体样式
            titleStyle.setFont(titleFont);
            // 列头样式
            CellStyle headerStyle = workbook.createCellStyle();
            // headerStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
            headerStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
            headerStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
            headerStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
            headerStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
            headerStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
            headerStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 垂直居中
            Font headerFont = workbook.createFont();
            headerFont.setFontHeightInPoints((short) 15); // 字体高度
            headerFont.setFontName("黑体"); // 字体样式
            headerStyle.setFont(headerFont);
            // 单元格样式
            CellStyle cellStyle = workbook.createCellStyle();
           /* cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);*/
            cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
            cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
            cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
            cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
            cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
            cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
            // 设置字体样式
            Font cellFont = workbook.createFont();
            titleFont.setFontHeightInPoints((short) 15); // 字体高度
            titleFont.setFontName("黑体"); // 字体样式
            cellStyle.setFont(cellFont);
            // 生成一个(带标题)表格
            SXSSFSheet sheet = (SXSSFSheet) workbook.createSheet();
            //设置列宽
            int minBytes = colWidth<DEFAULT_COLOUMN_WIDTH?DEFAULT_COLOUMN_WIDTH:colWidth;//至少字节数
            int[] arrColWidth = new int[headMap.size()];
            // 产生表格标题行,以及设置列宽
            String[] properties = new String[headMap.size()];
            String[] headers = new String[headMap.size()];
            int ii = 0;
            for (Iterator<String> iter = headMap.keySet().iterator(); iter
                    .hasNext();) {
                String fieldName = iter.next();
    
                properties[ii] = fieldName;
                headers[ii] = headMap.get(fieldName);
    
                int bytes = fieldName.getBytes().length;
                arrColWidth[ii] =  bytes < minBytes ? minBytes : bytes;
                sheet.setColumnWidth(ii,arrColWidth[ii]*256);
                ii++;
            }
            // 遍历集合数据,产生数据行
            int rowIndex = 0;
            for (Object obj : jsonArray) {
                if(rowIndex == 65535 || rowIndex == 0){
                    if ( rowIndex != 0 ) sheet = (SXSSFSheet) workbook.createSheet();//如果数据超过了,则在第二页显示
    
                    SXSSFRow titleRow = (SXSSFRow) sheet.createRow(0);//表头 rowIndex=0
                    titleRow.createCell(0).setCellValue(title);
                    titleRow.getCell(0).setCellStyle(titleStyle);
                    sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, headMap.size() - 1));
    
                    SXSSFRow headerRow = (SXSSFRow) sheet.createRow(1); //列头 rowIndex =1
                    for(int i=0;i<headers.length;i++)
                    {
                        headerRow.createCell(i).setCellValue(headers[i]);
                        headerRow.getCell(i).setCellStyle(headerStyle);
    
                    }
                    rowIndex = 2;//数据内容从 rowIndex=2开始
                }
                JSONObject jo = (JSONObject) JSONObject.toJSON(obj);
                SXSSFRow dataRow = (SXSSFRow) sheet.createRow(rowIndex);
                for (int i = 0; i < properties.length; i++)
                {
                    SXSSFCell newCell = (SXSSFCell) dataRow.createCell(i);
    
                    Object o =  jo.get(properties[i]);
                    if(o==null){
                        newCell.setCellValue("");
                    }else if(o instanceof Date){
                        String cellValue = new SimpleDateFormat(datePattern).format(o);
                        newCell.setCellValue(cellValue);
                    }else if(o instanceof Float || o instanceof Double || o instanceof BigDecimal){
                        newCell.setCellValue(Double.valueOf(o.toString()));
                    }else if(o instanceof Integer){
                        newCell.setCellValue(Integer.valueOf(o.toString()));
                    }else{
                        newCell.setCellValue(o.toString());
                    }
                    newCell.setCellStyle(cellStyle);
                }
                rowIndex++;
            }
            // 自动调整宽度
            /*for (int i = 0; i < headers.length; i++) {
                sheet.autoSizeColumn(i);
            }*/
            try {
                workbook.write(out);
                workbook.close();
                workbook.dispose();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //Web 导出excel
        public static void downloadExcelFile(String title,Map<String,String> headMap,JSONArray ja,HttpServletResponse response){
            try {
                System.out.println("开始写入"+System.currentTimeMillis());
                ByteArrayOutputStream os = new ByteArrayOutputStream();
                ExcelUtil.exportExcelX(title,headMap,ja,null,0,os);
                byte[] content = os.toByteArray();
                InputStream is = new ByteArrayInputStream(content);
                // 设置response参数,可以打开下载页面
                response.reset();
                response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
                response.setHeader("Content-Disposition", "attachment;filename="+ new String((title + ".xlsx").getBytes(), "iso-8859-1"));
                response.setContentLength(content.length);
                ServletOutputStream outputStream = response.getOutputStream();
                BufferedInputStream bis = new BufferedInputStream(is);
                BufferedOutputStream bos = new BufferedOutputStream(outputStream);
                byte[] buff = new byte[8192];
                int bytesRead;
                while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
                    bos.write(buff, 0, bytesRead);
    
                }
                bis.close();
                bos.close();
                outputStream.flush();
                outputStream.close();
                System.out.println("结束写入"+System.currentTimeMillis());
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
        //Web 导出excel
        public static void downloadExcelFile2(String title,Map<String,String> headMap,JSONArray ja,HttpServletResponse response){
            try {
                System.out.println("开始写入"+System.currentTimeMillis());
                ByteArrayOutputStream os = new ByteArrayOutputStream();
                ExcelUtil.exportExcelX2(title,headMap,ja,null,0,os);
                byte[] content = os.toByteArray();
                InputStream is = new ByteArrayInputStream(content);
                // 设置response参数,可以打开下载页面
                response.reset();
                response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
                response.setHeader("Content-Disposition", "attachment;filename="+ new String((title + ".xlsx").getBytes(), "iso-8859-1"));
                response.setContentLength(content.length);
                ServletOutputStream outputStream = response.getOutputStream();
                BufferedInputStream bis = new BufferedInputStream(is);
                BufferedOutputStream bos = new BufferedOutputStream(outputStream);
                byte[] buff = new byte[8192];
                int bytesRead;
                while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
                    bos.write(buff, 0, bytesRead);
    
                }
                bis.close();
                bos.close();
                outputStream.flush();
                outputStream.close();
                System.out.println("结束写入"+System.currentTimeMillis());
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }
    
    

    2.7.分组表格导出配置说明

    2.7. 分组表格导出配置说明

    配置

    1.对象建模–基础数据–POI配置管理,配置对应业务对象的导出数据。
    POI1
    2.POI模板说明:同普通表格设置相似,只有一点分组和普通表格不一样,就是分组且格模版中多了一个选项配置(如列上有配置统计类型需下面的配置):
    statistics:统计类型。是一个enum类型,目前只支持SUM(求和)、AVG(平均值)、
    例子:数据字典配置,统计配置(需把页面上的所有列都需加入模板中)
    POI2
    3.对象建模–业务对象–业务对象管理:编辑业务对象,点击方法定义Tab 点击【编辑】按钮,方法类型为表格页面数据导出
    POI3
    4.对象建模–业务对象–业务对象管理:编辑业务对象,管理页按钮中加入一个导出按钮指向刚新增那条导出方法。
    POI4
    5.生成相应代码即可。
    2.8.单表导出

    2.8. 单表导出

    配置

    1.制作导出模板:对象建模-业务对象:编辑业务对象,勾选生成导出模板,如下图:
    导出01

    2.在业务系统–>页面列表–>可视化布局–>把导出按钮显示出来。如果导出的字段为固定列则选择如下图导出按钮
    导出按钮
    3.如果导出的列根据表格上具体列导出,则选择下图左侧的表格列导出按钮。此步骤和上一步骤二选一导出即可。
    导出03
    4.提交对象。提交的时候会在基础数据-poi配置中生成对应的配置数据。其中模板路径为【/uploadFiles/local/模板文件名】。例如:【/uploadFiles/local/TestExam3101Template.xlsx】
    5.POI配置中需要将配置数据【同步到目标数据库】,如果不是开发库,可以【导出配置数据】,然后将导出的脚本刷新到对应的数据库中。
    导出POI

    6.生成业务对象代码。生成的时候会生成对应的模板文件。如果不需要再次生成模板文件,可将步骤一制作模板那个选项去掉即可。

    7.模板文件格式参考:
    导出模板
    1、普通文本字段:#!属性名,例如:#!itemName。
    2、下拉框字段:#!属性名{“dictionary”:”字典名”},例如:#!itemColor{“dictionary”:”Color”};如果是单层数据字典且有分组的:#!属性名{“dictionary”:”字典名$分组名”},例如:#!itemType{“dictionary”:”DICT_CODE$ITEM_TYPE”}。
    3、日期时间字段:#!属性名{“type”:”date”,”format”:”格式化”},例如:#!testTime{“type”:”date”,”format”:”yyyy-MM-dd hh:mm:ss”}。
    4、日期字段:#!属性名{“type”:”date”,”format”:”格式化”},例如:#!udf10{“type”:”date”,”format”:”yyyy-MM-dd”}。
    5、数值字段:#!属性名{“type”:”number”,”format”:”格式化”},例如:#!forbidenInbDays{“type”:”number”,”format”:”#,##0.00″}。
    6、地区控件:#!属性名{“dictionary”:”字典名”},例如:#!receiverArea{“dictionary”:”BasArea”}。如果需要全部路径的转换,需要扩展service,具体参考: gschool.glpaas.gillion.com.cn/?page_id=10918
    如果是地区控件要配置一个地区表的单层字典表,具体如下图:
    地区字典表

    2.9.主从表导出

    2.9. 主从表导出

    配置

    1.数据建模–>视图定义–>新增一个自定义SQL
    自定义SQL
    2.用自定义SQL创建一个业务对象,把这个业务对象生成代码拷到工程里面编译运行。
    SQL业务对象
    3.制作主从表导出模板,把主表字段放在子表字段的前面。
    主从导出模板
    4.基础数据–>POI配置–>新增一个导出POI配置
    与单表的区别在于POI对象全名的填写不一样,主从表的POI对象全名填写自定义SQL创建业务对象的domain地址。
    主从导出POI
    5.POI配置完要把数据刷到对应的业务系统数据库
    6.在业务系统–>页面列表–>可视化布局–>把导出按钮显示出来

    3.常用扩展 3. 常用扩展

    4. 版本更新 4. 版本更新

    7.4.1,2021.03.12

    优化

  • 【导出配置数据】如果勾选的是引用数据,提示【请回原视图导出配置数据!】。
  • 【同步到目标数据库】如果勾选的是引用数据,提示【请回原视图导出配置数据!】。
  • 查询界面优化。颜色标识,使用新表格。
  • 维护界面优化。业务对象联想控件过滤调整及去掉字段模块名称。
  • 5.6.0,2019.07.03

    新特性

  • 导出excel、导出EXCEL名称页面按照标题+年月日+时间(秒)命名