Java web项目使用Apache POI 实现对Excel的动态导入及导出

poi基本使用

HSSF — 提供读写Microsoft Excle格式档案的功能。 03版本(后缀为.xls)

XSSF — 提供读写Microsoft Excle OOXML格式档案的功能。 07版本(后缀为.xlsx)

HWPF — 提供读写Microsoft Word格式档案的功能。

HSLF — 提供读写Microsoft PowerPoint格式档案的功能。

HDGF — 提供读写Microsoft Visio格式档案的功能。

官方文档:https://poi.apache.org/index.html

poi中文api文档:https://www.cnblogs.com/fqfanqi/p/6172223.html

Apache POI 动态导入方法

依赖

<!--xls(03版)-->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>4.1.2</version>
</dependency>
<!--xlsx(07版)-->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.1.2</version>
</dependency>

web传excel文件简单导入

public static Map<?,?> importExcelData(MultipartFile file) throws IOException {
        InputStream inputStream = file.getInputStream();//得到文件的输入流
        Map excelData=new HashMap();//存储读取到的数据
        Map<Integer, String> titleMap = new HashMap<>();//存储表头信息
        Map<Integer, Map> contentsMap = new HashMap<>();//存储表格内容
        Map<String,Integer> oppTitleMap = new HashMap<>();
        Map<String,Integer> tipsMap = new HashMap<>();
        if(file.getOriginalFilename().endsWith(".xlsx")){//07版
            XSSFWorkbook wb = new XSSFWorkbook(inputStream);//建一个工作薄
            XSSFSheet sheet = wb.getSheetAt(0);//从文档中的第几张表开始,可写循环读取
            for (int i = sheet.getFirstRowNum(), rowCount = 0; rowCount < sheet.getPhysicalNumberOfRows(); i++) {
                XSSFRow row = sheet.getRow(i);//工作表的行数
                if (row == null) {
                    continue;
                }
                for (int j = row.getFirstCellNum(); j <= row.getLastCellNum(); j++) {
                    XSSFCell cell = row.getCell(j);//得到单元格信息
                    if (cell == null) {
                        continue;
                    }
                    //日期格式判断
                    CellType cellType = cell.getCellType();
                    String value =null;//单元格中数据
                    if(cellType==CellType.NUMERIC){
                         if (DateUtil.isCellDateFormatted(cell)){
                            Date date = cell.getDateCellValue();
                            //格式转换
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                            value = sdf.format(date);
                        }else {
                            cell.setCellType(CellType.STRING);//设置单元格数据格式
                            value = cell.getStringCellValue();
//                            value=String.valueOf(cell.getNumericCellValue());
                        }
                    }else{
                        cell.setCellType(CellType.STRING);
                        value = cell.getStringCellValue();
                    }

                    if (rowCount == 0) {//表头
                        titleMap.put(j, value);
                        if(oppTitleMap.get(value) != null){
                            tipsMap.put("出现重复标题:"+value,j);
                            continue;
                        }
                        oppTitleMap.put(value,j);
                    } else {//表内容
                        if (titleMap.size() == 0) {
                            return null;
                        }
                        Map contentMap = null;
                        if(contentsMap.get(rowCount)==null){
                            contentMap=new HashMap();
                        }else{
                            contentMap=contentsMap.get(rowCount);
                            if(contentMap.get(titleMap.get(j)) != null){
                                continue;
                            }
                        }
                        contentMap.put(titleMap.get(j), value);
                        contentsMap.put(rowCount,contentMap);
                    }
                }
                rowCount++;//下一行
            }
        }
        if(file.getOriginalFilename().endsWith(".xls")){//03版
            HSSFWorkbook wb = new HSSFWorkbook(file.getInputStream());//创建工作簿
            HSSFSheet sheet = wb.getSheetAt(0);//得到表
            for (int i = sheet.getFirstRowNum(), rowCount = 0; rowCount < sheet.getPhysicalNumberOfRows(); i++) {
                HSSFRow row = sheet.getRow(i);//得到行
                if (row == null) {
                    continue;
                }
                for (int j = row.getFirstCellNum(); j <= row.getLastCellNum(); j++) {
                    HSSFCell cell = row.getCell(j);//得到列
                    if (cell == null) {
                        continue;
                    }
                    //日期格式判断
                    CellType cellType = cell.getCellType();
                    String value =null;//单元格中数据
                    if(cellType==CellType.NUMERIC){
                         if (DateUtil.isCellDateFormatted(cell)){
                            Date date = cell.getDateCellValue();
                            //格式转换
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                            value = sdf.format(date);
                        }else {
                            cell.setCellType(CellType.STRING);
                            value = cell.getStringCellValue();
                        }
                    }else{
                        cell.setCellType(CellType.STRING);
                        value = cell.getStringCellValue();
                    }

                    if (rowCount == 0) {//表头
                        titleMap.put(j, value);
                        if(oppTitleMap.get(value) != null){
                            tipsMap.put("出现重复标题:"+value,j);
                            continue;
                        }
                        oppTitleMap.put(value,j);
                    } else {//表内容
                        if (titleMap.size() == 0) {
                            return null;
                        }
                        Map contentMap = null;
                        if(contentsMap.get(rowCount)==null){
                            contentMap=new HashMap();
                        }else{
                            contentMap=contentsMap.get(rowCount);
                            if(contentMap.get(titleMap.get(j)) != null){
                                continue;
                            }
                        }
                        contentMap.put(titleMap.get(j), value);
                        contentsMap.put(rowCount,contentMap);
                    }
                }
                rowCount++;//下一行
            }
        }
        inputStream.close();//关闭流
        excelData.put("contents",contentsMap);//数据内容
        excelData.put("title",titleMap);//表头
        excelData.put("oppTitle",oppTitleMap);//表头索引
        excelData.put("tips",tipsMap);//提示
        return excelData;
    }

说明:

1、获取表头:Map titleMap = (Map) excelData.get("title");

对应数据key从0开始,获得每个单元格的数据。

2、获取内容:Map contents = (Map) excelData.get("contents");

对应数据key从1开始,获得每一行与表头对应的数据map,key为表头内容,value为对应行单元格内容。

3、在文件传入时可以做一个校验,校验格式是否为.xls 或 .xlsx

4、日期格式不支持自定义,仅支持默认日期格式

其他poi

EasyPoi

基于entity变量上的注解,非常简单的一种方式,兼容性很好

官方文档:http://doc.wupaas.com/docs/easypoi/easypoi-1c0u6ksp2r091

相关csdn博客:https://blog.csdn.net/qq_41964942/article/details/124635584

<!--easypoi springboot-->
<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-spring-boot-starter</artifactId>
    <version>4.4.0</version>
</dependency>

阿里easyExcel

同样基于注解的形式,对动态表头导出支持性比较好。

官方文档:https://easyexcel.opensource.alibaba.com/

相关csdn博客:https://blog.csdn.net/weixin_42083036/article/details/116750910

<!--easyexcel-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>2.2.6</version>
</dependency>

java web项目前端ajax请求后端导出Excel

前端ajax请求

$.ajax({
    type: "POST",
    data:JSON.stringify({数据}),
    contentType: 'application/json',
    xhrFields: {responseType: "blob"},
    url: exportUrl,
    success: function (result) {
        var link = document.createElement('a');
        let blob = new Blob([result], {type: 'application/vnd.ms-excel'});
        link.style.display = 'none';
        link.href = URL.createObjectURL(blob);
        link.setAttribute('download', "文档名称.xlsx");
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link)
        layer.msg("导出成功!");
    },
    error: function(){
        layer.msg("导出失败!");
    }
});

//使用layui的方法纯前端导出
// var fileName='文档名称.xlsx';
// var datas = [];
// var map ={};
// for(var i=3;i<colsArr.length-4;i++){
//     if(colsArr[i].title=='负责部门' || colsArr[i].title=='负责人'){
//         continue;
//     }
//     var dataName = "data_"+i;
//     var hInfo=colsArr[i].title;
//     map[dataName] = hInfo;
// }
// datas.push(map);
// layui.excel.exportExcel({
//     sheet: datas
// }, fileName, 'xlsx');

后端Controller代码

/**
 * Excel举措模板导出
 * @return
 */
@PostMapping("/export")
@ApiOperation(value = "Excel举措模板导出", notes = "Excel举措模板导出")
public void export(@RequestBody 接收实体类,HttpServletResponse response) throws IOException {
    XSSFWorkbook wb = new XSSFWorkbook();//创建工作簿
    XSSFSheet sheet = wb.createSheet("表名");//创建表
    XSSFRow headRow=sheet.createRow(0);//创建表头
    //获取表头数据 headLis
    for(int i = 0; i< headList.size();i++){
        headItem =headList.get(i);
        XSSFCell headRowCell=headRow.createCell(i);//创建表头单元格
        headRowCell.setCellValue(headItem.getLmmiTitle());

        //设置单元格中文字颜色为红色
        if(true){
            XSSFCellStyle cellStyle = wb.createCellStyle();
            XSSFFont font = wb.createFont();
            font.setColor(XSSFFont.COLOR_RED);
            cellStyle.setFont(font);
            headRowCell.setCellStyle(cellStyle);
        }

        //单选多选设置
        if(StrUtil.equals("radio",headItem.getType()) || StrUtil.equals("checkbox",headItem.getType())){
            DataValidationHelper helper = new XSSFDataValidationHelper(sheet);
            // 给内容行设置下拉列表内容
            CellRangeAddressList contentRowCellList = new CellRangeAddressList(1,1, i,i);// 数据有效性被设置对象
            DataValidationConstraint dataValidationConstraint = helper.createExplicitListConstraint(headItem.getDataList().split("\n"));
            DataValidation data_validation_list = helper.createValidation(dataValidationConstraint, contentRowCellList);
            sheet.addValidationData(data_validation_list);

            // 给表头创建一个提示,当包含数据验证的单元格收到焦点时,用户将看到该提示
            DataValidation data_validation_view = helper.createValidation(dataValidationConstraint, new CellRangeAddressList(0,0, i,i));
            if(StrUtil.equals("checkbox",headItem.getType())){
                data_validation_view.createPromptBox("提示:", "多选列");
            }else{
                data_validation_view.createPromptBox("提示:", "单选列");
            }
            data_validation_view.setShowPromptBox(true);
            sheet.addValidationData(data_validation_view);

            //创建一个消息框,如果用户输入的值无效,将向用户显示该消息框。
            dataValidation1.setErrorStyle(HSSFDataValidation.ErrorStyle.STOP);
            dataValidation1.createErrorBox("提示", "不允许自己输入,请选择下拉框里的数据");
        }

        //日期行提示
        if(StrUtil.equals("text-time",headItem.getType())){
            DataValidationHelper helper = new XSSFDataValidationHelper(sheet);
            // 创建一个提示,当包含数据验证的单元格收到焦点时,用户将看到该提示
            DataValidationConstraint dataValidationConstraint = helper.createCustomConstraint(String.valueOf(DataValidationConstraint.ValidationType.DATE));
            DataValidation data_validation_view = helper.createValidation(dataValidationConstraint, new CellRangeAddressList(0,0, i,i));
            data_validation_view.createPromptBox("提示:", "不支持自定义日期格式");
            data_validation_view.setShowPromptBox(true);
            sheet.addValidationData(data_validation_view);
        }

        //首行数据列显示默认值
        if(StrUtil.isNotEmpty(headItem.getDefaultValue())){
            if(sheet.getRow(1)==null){
                XSSFRow contentRow=sheet.createRow(1);//创建内容
                XSSFCell contentRowCell=contentRow.getCell(i);
                if(contentRowCell==null){
                    contentRowCell = contentRow.createCell(i);
                }
                contentRowCell.setCellValue(headItem.getDefaultValue());
            }
        }
    }

    //输出Excel文件
    response.setContentType("application/vnd.ms-excel;charset=utf-8");
    response.setHeader("Content-Disposition",
            "attachment;filename=\"" + new String(("文档名称.xlsx").getBytes("gb2312"), "ISO8859-1"));
    OutputStream output=response.getOutputStream();
    wb.write(output);
    output.close();
}

参考文章:

前端请求:https://www.cnblogs.com/CF1314/p/16331514.html

下拉框:https://blog.csdn.net/ggjklncffd/article/details/124691930

样式:https://blog.csdn.net/weixin_44870420/article/details/126936965

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值