POI导出Excel文档

首次接触POI,准备把这次经历记录下来。先介绍导出的功能:

首先是针对前端的利用ajax请求

<a href="javascript:printFInfo()" class="easyui-linkbutton"
						data-options="iconCls:'icon-print'">导出</a>

----------------------------------------------------------------------------
<script type="text/javascript">
    function printFInfo(){
        $.ajax({
	    type:"post",
	    url:"${ctx }/bom/bomExport.do",
	    data : {
	     	billNo : billNO
	    },
	    dataType : "json",
	    success:function(data){
	  	    if(data=="1"){
	  	    	$.messager.show({
	  	    		title : '提示:',
	  	    		msg : '导出成功!文件在桌面 O ~ ~'
	  	    	});
	  	    }else{
	  	    	$.messager.show({
	  	    		title : '提示:',
	  	    		msg : '导出失败!请联系管理员。'
	  	    	});
	  	    }  
	     }
	});
    }
</script>

直接跳到service层

@Override
    public void bomExport(String billNo) {
        //获取需导出的数据
        List<OrderBom> orderBoms = orderBomDao.getBomInfos(billNo);
        // 生成表格标题行
        String[] headers = { "分级层次", "生产订单号", "物料代码", "物料名称", "规格型号", "物料属性", "单位", "用量", "损耗", "净重", "供应商", "计划跟踪号",
                "计划模式" };
        // -----设置导出表格-----
        // 声明一个工作薄
        HSSFWorkbook workbook = new HSSFWorkbook();
        // 生成一个表格
        HSSFSheet sheet = workbook.createSheet("订单BOM信息");
        // 设置表格默认列宽度为15个字节
        sheet.setDefaultColumnWidth(15);
        sheet.autoSizeColumn(1, true);
        // 生成一个样式
        HSSFCellStyle style = workbook.createCellStyle();
        // 设置这些样式
        style.setAlignment(HSSFCellStyle.ALIGN_LEFT);
        style.setVerticalAlignment(org.apache.poi.ss.usermodel.CellStyle.VERTICAL_CENTER);
        style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        style.setBorderRight(HSSFCellStyle.BORDER_THIN);
        style.setBorderTop(HSSFCellStyle.BORDER_THIN);
        // 生成一个字体
        HSSFFont font = workbook.createFont();
        font.setFontHeightInPoints((short) 12);
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        // 把字体应用到当前的样式
        style.setFont(font);
        // 生成并设置另一个样式
        HSSFCellStyle style2 = workbook.createCellStyle();
        style2.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        style2.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        style2.setBorderRight(HSSFCellStyle.BORDER_THIN);
        style2.setBorderTop(HSSFCellStyle.BORDER_THIN);
        // 生成另一个字体
        HSSFFont font2 = workbook.createFont();
        font2.setFontName("宋体");
        // 把字体应用到当前的样式
        style2.setFont(font2);
        // 产生表格标题行
        HSSFRow row = sheet.createRow(0);
        row.setHeightInPoints(30);
        for (int k = 0; k < headers.length; k++) {
            HSSFCell cell = row.createCell(k);
            cell.setCellStyle(style);
            HSSFRichTextString text = new HSSFRichTextString(headers[k]);
            cell.setCellValue(text);
        }
        // 写入查询数据,并设置样式
        for (OrderBom orderBom : orderBoms) {
            int lastRowNum = sheet.getLastRowNum() + 1;// 当前需要增加行的下标
            row = sheet.createRow(lastRowNum);
            row.setHeightInPoints(20);
            row.createCell(0).setCellValue(orderBom.getFlevel());
            row.createCell(1).setCellValue(billNo);
            row.createCell(2).setCellValue(orderBom.getFnumber());
            row.createCell(3).setCellValue(orderBom.getFname());
            row.createCell(4).setCellValue(orderBom.getFmodel());
            row.createCell(5).setCellValue(orderBom.getFattribute());
            row.createCell(6).setCellValue(orderBom.getFunit());
            row.createCell(7).setCellValue(orderBom.getFdosage());
            row.createCell(8).setCellValue(orderBom.getFloss());
            row.createCell(9).setCellValue(orderBom.getFnetWeight());
            row.createCell(10).setCellValue(orderBom.getFsupplier());
            row.createCell(11).setCellValue(orderBom.getFplanNum());
            row.createCell(12).setCellValue(orderBom.getFplanMode());
            for (int j = 0; j < headers.length; j++) {
                row.getCell(j).setCellStyle(style2);
            }
        }
        // 将文件存储到指定位置
        // 获取桌面路径
        FileSystemView fsv = FileSystemView.getFileSystemView();
        String desktop = fsv.getHomeDirectory().getPath();
        String filePath = desktop + "/报关BOM信息." + time + ".xls";
        File file = new File(filePath);
        FileOutputStream fout = new FileOutputStream(file);
        try {
            workbook.write(fout);
            fout.flush();
            fout.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

这就能完成简单的导出文件,需要注意的是这种自动获取路径的方式,有缺陷!只能下载在服务器的桌面路径,所以测试用这种方式可以,但是实际还是要让用户自己选择路径下载,这就不能用ajax了。接下来介绍另一种:

//打印报表信息
function printFInfo(){
    if(billNO!=null){
    	location.href="${ctx }/bom/bomInfosPrint.do?billNo="+billNO;
    }
}

在Controller层用request获取参数

/**
     * 订单BOM信息导出
     * 
     * @return
     */
    @RequestMapping({ "bomInfosPrint.do" })
    @ResponseBody
    public void bomInfosPrint(HttpServletResponse response, HttpServletRequest request) {
        // 切换数据库
        String billNo = request.getParameter("billNo").toString();
        CustomerContextHolder.setCustomerType("mssqlDataSource");
        orderBomService.bomExport(billNo, response);
        CustomerContextHolder.clearCustomerType();
    }

 这是service层的内容。

@Override
    public void bomExport(String billNo, HttpServletResponse response) {
        List<OrderBom> orderBoms = orderBomDao.getBomInfos(billNo);
        // 生成表格标题行
        String[] headers = { "分级层次", "生产订单号", "物料代码", "物料名称", "规格型号", "物料属性", "单位", "用量", "损耗", "净重", "供应商", "计划跟踪号",
                "计划模式" };
        // -----设置导出表格-----
        // 声明一个工作薄
        HSSFWorkbook workbook = new HSSFWorkbook();
        // 生成一个表格
        HSSFSheet sheet = workbook.createSheet("订单BOM信息");
        // 设置表格默认列宽度为15个字节
        sheet.setDefaultColumnWidth(15);
        sheet.autoSizeColumn(1, true);
        // 生成一个样式
        HSSFCellStyle style = workbook.createCellStyle();
        // 设置这些样式
        style.setAlignment(HSSFCellStyle.ALIGN_LEFT);
        style.setVerticalAlignment(org.apache.poi.ss.usermodel.CellStyle.VERTICAL_CENTER);
        style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        style.setBorderRight(HSSFCellStyle.BORDER_THIN);
        style.setBorderTop(HSSFCellStyle.BORDER_THIN);
        // 生成一个字体
        HSSFFont font = workbook.createFont();
        font.setFontHeightInPoints((short) 12);
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        // 把字体应用到当前的样式
        style.setFont(font);
        // 生成并设置另一个样式
        HSSFCellStyle style2 = workbook.createCellStyle();
        style2.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        style2.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        style2.setBorderRight(HSSFCellStyle.BORDER_THIN);
        style2.setBorderTop(HSSFCellStyle.BORDER_THIN);
        // 生成另一个字体
        HSSFFont font2 = workbook.createFont();
        font2.setFontName("宋体");
        // 把字体应用到当前的样式
        style2.setFont(font2);
        // 产生表格标题行
        HSSFRow row = sheet.createRow(0);
        row.setHeightInPoints(30);
        for (int k = 0; k < headers.length; k++) {
            HSSFCell cell = row.createCell(k);
            cell.setCellStyle(style);
            HSSFRichTextString text = new HSSFRichTextString(headers[k]);
            cell.setCellValue(text);
        }
        // 写入查询数据,并设置样式
        for (OrderBom orderBom : orderBoms) {
            int lastRowNum = sheet.getLastRowNum() + 1;// 当前需要增加行的下标
            row = sheet.createRow(lastRowNum);
            row.setHeightInPoints(20);
            row.createCell(0).setCellValue(orderBom.getFlevel());
            row.createCell(1).setCellValue(billNo);
            row.createCell(2).setCellValue(orderBom.getFnumber());
            row.createCell(3).setCellValue(orderBom.getFname());
            row.createCell(4).setCellValue(orderBom.getFmodel());
            row.createCell(5).setCellValue(orderBom.getFattribute());
            row.createCell(6).setCellValue(orderBom.getFunit());
            row.createCell(7).setCellValue(orderBom.getFdosage());
            row.createCell(8).setCellValue(orderBom.getFloss());
            row.createCell(9).setCellValue(orderBom.getFnetWeight());
            row.createCell(10).setCellValue(orderBom.getFsupplier());
            row.createCell(11).setCellValue(orderBom.getFplanNum());
            row.createCell(12).setCellValue(orderBom.getFplanMode());
            for (int j = 0; j < headers.length; j++) {
                row.getCell(j).setCellStyle(style2);
            }
        }
        // 创建response输出流
        SimpleDateFormat df = new SimpleDateFormat("yyMMdd-HH.mm");// 设置日期格式
        String time = df.format(new Date());// new Date()为获取当前系统时间
        OutputStream os = null;
        try {
            os = response.getOutputStream();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        response.reset();
        String filename = "订单BOM信息." + time + ".xls";
        response.setContentType("application/msexcel");
        try {
            response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
            workbook.write(os);
            os.flush();
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

这样子就可以让用户自己选择下载路径了。

做项目时有一个需求,数据做成树形结构后只取它最下阶导出,我刚开始用了很多个if判断,后来发现不对劲,做了一个递归循环,记录一下:

@Override
    public void customBomExport(String billNo, HttpServletResponse response) {
        // 获取数据
        List<OrderBom> orderBoms = orderBomDao.getBomInfos(billNo);
        List<OrderBom> product = new ArrayList<OrderBom>();
        Double k = null;
        int indexOf = 0;
        for (OrderBom orderBom : orderBoms) {
            if (orderBom.get_parentId() == null) {
                indexOf = orderBoms.indexOf(orderBom);
                k = orderBom.getFdosage();
                product.add(orderBom);
            }
        }
        orderBoms.remove(indexOf);
        // 生成表格标题行
        String[] headers = { "成品货号", "料件货号", "内部版本号", "备案版本号", "ERP单耗", "有形损耗率", "无形损耗率", "保税比例", "申报单耗", "开始日期",
                "结束日期", "备注" };
        // -----设置导出表格-----
        // 声明一个工作薄
        HSSFWorkbook workbook = new HSSFWorkbook();
        // 生成一个表格
        HSSFSheet sheet = workbook.createSheet("企业成品耗用");
        // 设置表格默认列宽度为15个字节
        sheet.setDefaultColumnWidth(15);
        sheet.autoSizeColumn(1, true);
        // 生成一个样式
        HSSFCellStyle style = workbook.createCellStyle();
        // 设置这些样式
        style.setAlignment(HSSFCellStyle.ALIGN_LEFT);
        style.setVerticalAlignment(org.apache.poi.ss.usermodel.CellStyle.VERTICAL_CENTER);
        style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        style.setBorderRight(HSSFCellStyle.BORDER_THIN);
        style.setBorderTop(HSSFCellStyle.BORDER_THIN);
        style.setFillForegroundColor(IndexedColors.LEMON_CHIFFON.getIndex());
        style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
        // 生成一个字体
        HSSFFont font = workbook.createFont();
        font.setFontHeightInPoints((short) 12);
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        // 把字体应用到当前的样式
        style.setFont(font);
        // 生成并设置另一个样式
        HSSFCellStyle style2 = workbook.createCellStyle();
        style2.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        style2.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        style2.setBorderRight(HSSFCellStyle.BORDER_THIN);
        style2.setBorderTop(HSSFCellStyle.BORDER_THIN);
        style2.setAlignment(HSSFCellStyle.ALIGN_LEFT);
        style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        style2.setFillForegroundColor(IndexedColors.LEMON_CHIFFON.getIndex());
        style2.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
        // 生成另一个字体
        HSSFFont font2 = workbook.createFont();
        font2.setFontName("宋体");
        font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
        // 把字体应用到当前的样式
        style2.setFont(font2);
        // 产生表格标题行
        HSSFRow row = sheet.createRow(0);
        row.setHeightInPoints(30);
        for (int x = 0; x < headers.length; x++) {
            HSSFCell cell = row.createCell(x);
            cell.setCellStyle(style);
            HSSFRichTextString text = new HSSFRichTextString(headers[x]);
            cell.setCellValue(text);
        }
        // 二维数组转树形
        List<OrderBom> nodeList = new ArrayList<OrderBom>();
        boolean mark;
        for (OrderBom ob : orderBoms) {
            mark = false;
            for (OrderBom ob2 : orderBoms) {
                if (ob.get_parentId() != null && ob.get_parentId().equals(ob2.getId())) {
                    mark = true;
                    if (ob2.getChildren() == null) {
                        ob2.setChildren(new ArrayList<OrderBom>());
                        ob2.getChildren().add(ob);
                    } else {
                        ob2.getChildren().add(ob);
                    }
                }
            }
            if (!mark) {
                nodeList.add(ob);
            }
        }
     // 设置日期格式
        SimpleDateFormat tf = new SimpleDateFormat("yyyy-MM-dd");
        Integer lastRowNum = null;// 当前需要增加行的下标
        String beginDate = null;
        //将参数传进去后递归循环写入数据
        judgeNull(nodeList, headers, sheet, style2, row, lastRowNum, beginDate, tf, product, billNo);
        // 创建response输出流
        SimpleDateFormat df = new SimpleDateFormat("yyMMdd-HH.mm");// 设置日期格式
        String time = df.format(new Date());// new Date()为获取当前系统时间
        OutputStream os = null;
        try {
            os = response.getOutputStream();
        } catch (IOException e1) {
        }
        response.reset();
        String filename = billNo + "." + time + ".xls";
        response.setContentType("application/msexcel");
        try {
            response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
            workbook.write(os);
            os.flush();
            os.close();
        } catch (Exception e) {
        }
    }

    //写入数据并设置样式
    private void judgeNull(List<OrderBom> orderBoms, String[] headers, HSSFSheet sheet, HSSFCellStyle style2,
            HSSFRow row, Integer lastRowNum, String beginDate, SimpleDateFormat tf, List<OrderBom> product,
            String billNo) {
        for (OrderBom orderBom : orderBoms) {
            List<OrderBom> children = orderBom.getChildren();
            if (children != null) {
                judgeNull(children, headers, sheet, style2, row, lastRowNum, beginDate, tf, product, billNo);
            } else {
                // 写入数据
                lastRowNum = sheet.getLastRowNum() + 1;
                row = sheet.createRow(lastRowNum);
                row.setHeightInPoints(20);
                row.createCell(0).setCellValue(product.get(0).getFnumber());
                row.createCell(1).setCellValue(orderBom.getFnumber());
                row.createCell(2).setCellValue(billNo);
                row.createCell(3).setCellValue("");
                row.createCell(4).setCellValue(orderBom.getFdosage());// ERP单耗
                row.createCell(5).setCellValue(0);
                row.createCell(6).setCellValue(0);
                row.createCell(7).setCellValue(100);
                row.createCell(8).setCellValue("");
                beginDate = tf.format(orderBom.getBeginDate()); // 格式化日期
                row.createCell(9).setCellValue(beginDate);
                row.createCell(10).setCellValue("");
                row.createCell(11).setCellValue("");
                for (int j = 0; j < headers.length; j++) {
                    row.getCell(j).setCellStyle(style2);
                }
            }
        }
    }

 

先完成到这,初步涉略,讲的不是很细,后续有想法了再补充,欢迎各位指点~~

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值