java实现Excel导出功能-poi

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/MaBanSheng/article/details/83547548

一、jar包
从maven仓库下载即可,我是基于项目新加了这些jar包,应该还需要logging包,大家慢慢调试就行,缺哪个就导进哪一个
poi-3.16.jar;
poi-ooxml-3.16.jar;
poi-ooxml-schemas-3.16.jar;
xmlbeans-2.6.0.jar;
commons-collections4-4.1,jar

二、工具类(拷贝网络上资源)
//调用方法传递四个参数
//1、title:表中第一行显示表主旨
//2、headmap:表头数据
//3、datalist:表中数据
//4、datePattern:处理日期格式
//5、colwidth:列宽
//6、out:输出流
public class ExcelUtils {
public static String NO_DEFINE = “no_define”;//未定义的字段

public static String DEFAULT_DATE_PATTERN = "yyyy-MM-dd";//默认日期格式

public static int DEFAULT_COLOUMN_WIDTH = 17;//默认列宽

/**
 * 导出Excel
 *
 * @param title
 * @param headMap
 * @param dataList
 * @param datePattern
 * @param colWidth
 * @param out
 */
public static void exportExcel(String title, Map<String, String> headMap, List<Map> dataList,
                               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.setAlignment(HorizontalAlignment.CENTER);
    Font titleFont = workbook.createFont();
    titleFont.setFontHeightInPoints((short) 20);
    titleStyle.setFont(titleFont);
    // 列头样式
    CellStyle headerStyle = workbook.createCellStyle();
    headerStyle.setBorderLeft(BorderStyle.THIN);
    headerStyle.setBorderRight(BorderStyle.THIN);
    headerStyle.setBorderTop(BorderStyle.THIN);
    headerStyle.setBorderBottom(BorderStyle.THIN);
    headerStyle.setAlignment(HorizontalAlignment.CENTER);

    Font headerFont = workbook.createFont();
    headerFont.setFontHeightInPoints((short) 12);
    headerStyle.setFont(headerFont);
    // 单元格样式
    CellStyle cellStyle = workbook.createCellStyle();
    cellStyle.setBorderLeft(BorderStyle.THIN);
    cellStyle.setBorderRight(BorderStyle.THIN);
    cellStyle.setBorderTop(BorderStyle.THIN);
    cellStyle.setBorderBottom(BorderStyle.THIN);
    cellStyle.setAlignment(HorizontalAlignment.CENTER);
    cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
    Font cellFont = workbook.createFont();
    cellFont.setFontHeightInPoints((short) 12);
    cellStyle.setFont(cellFont);
    // 生成一个(带标题)表格
    SXSSFSheet sheet = 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 (Map obj : dataList) {
        if (rowIndex == 0) {
            SXSSFRow 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));
            SXSSFRow 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开始
        }
        SXSSFRow dataRow = sheet.createRow(rowIndex);
        for (int i = 0; i < properties.length; i++) {
            SXSSFCell newCell = dataRow.createCell(i);
            Object o = obj.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++;
    }
    try {
        workbook.write(out);
        workbook.close();
        workbook.dispose();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

}
三、controller层
这里根据各自项目,拼凑工具类方法参数。我的如下:

@RequestMapping(value = "/exportExcel", method = RequestMethod.GET)
@ResponseBody
public void exportExcel(HttpServletRequest request, HttpServletResponse response) {
    OutputStream outputStream = null;
    try {
        Map<String, Object> reqMap = new HashMap<String, Object>();
        Map<String, Object> params = MyEntityUtils.getRequestParams(request);
        params.put("orgId", SessionUtils.getLoginUser().getOrgid());
        params.put("action", "q_param");
        //处理导出按钮传来的参数
        String decode = URLDecoder.decode(String.valueOf(params.get("search")), "UTF-8");
        Map searchMap = (Map) JSON.parse(decode);
        params.putAll(searchMap);
        reqMap.put("datajson", JSON.toJSONString(params));
        /**
         * 拼凑excel工具类的入参
         */
        //执行查询获取excel中的数据
        List<Map> list = depositConfirmationService.queryDepositConfirmationList(reqMap);
        //第一列大表名
        String sheetName = "保证金确认函";
      
        Map<String, Object> headParam = new HashMap<String, Object>();
        headParam.put("menuid","103002007");
        List<Map> headList = pageConfService.getPageQueryResultByMap(headParam);
        Map<String, String> headMap = new HashMap<>();
        if (headList != null && headList.size()>0) {
            for (Map map : headList) {
                headMap.put((String) map.get("field"),(String) map.get("title"));
            }
        }
        //设置response
        response.reset();
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename="+ new String(("保证金确认函.xlsx").getBytes(), "iso-8859-1"));
        outputStream = response.getOutputStream();
        //调用工具类方法将workbook写入到流中
        ExcelUtils.exportExcel(sheetName,headMap,list,null,0,outputStream);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (outputStream != null) {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

四、前台点击按钮执行导出
注意这里使用ajax是不行的。

    $("#btnExport").click(function () {
        var search = $("#mysearch").serializeObject();//获取查询条件
        location.href = "/a/b/c/exportExcel.do?search="+encodeURI(encodeURI(JSON.stringify(search)));
    })

五、特别说明
前后台查询参数汉字会乱码,前台使用encodeURI(encodeURI()),后台使用URLDecoder.decode(str, “UTF-8”)就可以解决。

猜你喜欢

转载自blog.csdn.net/MaBanSheng/article/details/83547548