zoukankan      html  css  js  c++  java
  • Spring Boot学习笔记----POI(Excel导入导出)

    业务:动态生成模板导出Excel,用户修改完再导入Excel.

    Spring boot + bootstrap + poi

    1.添加Dependence

    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>3.17</version>
    </dependency>
    
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>3.17</version>
    </dependency>

    前者用于引入HSSFWorkbook;后者用于引入XSSFWorkbook.

    2.生成模板并导出Excel

    //生成模板
    function modleCreate(){
        //清空数据
        var oaId= $("#adjOAId").val();
        var adjOrg= $("#adjOrg").val();
        var adjDepart=$("#adjDepart").val();
        var adjSubject=$("#adjSubject").val();
        window.location.href="budgetOaController/exportTemplate?adjOrg="+ adjOrg +"&&adjDepart=" +adjDepart +"&&adjSubject="+adjSubject+"&&oaId="+oaId;
    }    
        @RequestMapping(value="/exportTemplate",method=RequestMethod.GET) 
        public void exportTemplate(HttpServletResponse response,@RequestParam String adjOrg,@RequestParam String adjSubject,
                @RequestParam String adjDepart,@RequestParam String oaId) throws IOException{
                 // 声明一个工作薄        
                HSSFWorkbook workbook = new HSSFWorkbook();
                //创建一个Excel表单,参数为sheet的名字
                HSSFSheet sheet = workbook.createSheet("模板表");
                //创建表头
                setTitle(workbook, sheet);
                List<Map<String, Object>> oalist = budgetAdjustService.getOainform(oaId);
                //新增数据行,并且设置单元格数据
                    HSSFRow hssfRow = sheet.createRow(1);
                    for(Map map :oalist) {
                    hssfRow.createCell(0).setCellValue(map.get("adjustType")+"");
                   hssfRow.createCell(1).setCellValue(map.get("applyDate")+"");
                   hssfRow.createCell(2).setCellValue(map.get("processCode")+"");
                   hssfRow.createCell(3).setCellValue(map.get("applyOrganization")+"");
                   hssfRow.createCell(4).setCellValue(map.get("applyDepartment")+"");
                   hssfRow.createCell(5).setCellValue(map.get("flag")+"");
                    }
                hssfRow.createCell(6).setCellValue(adjOrg);
                hssfRow.createCell(7).setCellValue(adjDepart);
                hssfRow.createCell(8).setCellValue(adjSubject);
                     /*hssfRow.createCell(1).setCellValue(budgetadjust.getApplyDate());
                     hssfRow.createCell(2).setCellValue(budgetadjust.getProcessCode());
                     hssfRow.createCell(3).setCellValue(budgetadjust.getApplyOrganization());
                     hssfRow.createCell(4).setCellValue(budgetadjust.getApplyDepartment());
                     hssfRow.createCell(5).setCellValue(budgetadjust.getFlag());
                     hssfRow.createCell(6).setCellValue(budgetadjust.getExportorganization());
                     hssfRow.createCell(7).setCellValue(budgetadjust.getExportdepartment());
                     hssfRow.createCell(8).setCellValue(budgetadjust.getExportsubject());
                 }*/
                // SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
                 String fileName = "Template -" + new Date().getTime() + ".xls";
                //清空response  
                response.reset();  
                //设置response的Header  
                response.addHeader("Content-Disposition", "attachment;filename="+ fileName);  
                OutputStream os = new BufferedOutputStream(response.getOutputStream());  
                response.setContentType("application/vnd.ms-excel;charset=gb2312"); 
                //将excel写入到输出流中
                workbook.write(os);
                os.flush();
                os.close();
            }
    
        // 创建表头
        private void setTitle(HSSFWorkbook workbook, HSSFSheet sheet) {
            HSSFRow row = sheet.createRow(0);
            // 设置列宽,setColumnWidth的第二个参数要乘以256,这个参数的单位是1/256个字符宽度
            sheet.setColumnWidth(8, 60 * 256);
            // 设置为居中加粗
            HSSFCellStyle style = workbook.createCellStyle();
            HSSFFont font = workbook.createFont();
            font.setBold(true);
            style.setFont(font);
            //导出的Excel头部
            String[] headers = { "调整类型", "申请日期", "OA流程编号", "申请组织", "申请部门", "是否涉及人力成本", "调出组织", "调出部门", "调出科目", "调出月份",
                    "调出金额", "查询费控系统", "调入组织", "调入部门", "调入科目", "调入月份", "调入金额", "调整原因" };
            // 设置表格默认列宽度为15个字节
            sheet.setDefaultColumnWidth((short) 16);
            for (short i = 0; i < headers.length; i++) {
                HSSFCell cell = row.createCell(i);
                HSSFRichTextString text = new HSSFRichTextString(headers[i]);
                cell.setCellValue(text);
                cell.setCellStyle(style);
            }
        }

     2.1 导出结果

    3.导入Excel

    <div class="row">
        <div class="col-md-12">
            <section class="panel">
                <header class="panel-heading">
                    OA预算调整模板导入
                </header>
                    <div class="modal-body">
                        <div class="row">
                            <div class="col-lg-12">
                                <form id="defaultForm" method="" class="form-horizontal recoveryNodeForm" action="">
                                    <div class="col-lg-12">
                                        <div class="form-group">
                                            <label class="col-lg-3 control-label">导入文件</label>
                                            <div class="col-lg-6">
                                                <input type="file" class="form-control" style="height:36px;" name="uploadFile" id="uploadFile"/>
                                            </div>
                                            <button type="button" class="btn btn-primary" id="uploadExcel">上传</button>
                                        </div>
                                    </div>
                                    <input type="hidden" name="pkId" value="" />
                                </form>
                            </div>
                        </div>
                        <div>
                            <span><b>导入结果反馈</b></span>
                            <ul id="exportResult">
                            </ul>
                        </div>
                    </div>
                        
            </section>
        </div>
    </div>
    
    <!-- 工具JS由开发人员编写 -->
    <script th:inline="javascript">
        /*<![CDATA[*/
    $(function(){
        $(".recoveryNodeForm").bootstrapValidator({
            message: 'This value is not valid',
            live: 'submitted',
            fields: {/*验证*/
                uploadFile: {
                    message: '导入文件无效',
                    validators: {
                        notEmpty: {/*非空提示*/
                            message: '导入文件不能为空'
                        },
                        regexp: {
                            regexp: /.xl(s[xmb]|t[xm]|am|s)$/,
                            //regexp: /.xls$/,
                           // extension: 'zip,rar,doc,docx,pdf',
                            message: '导入文件类型必须是excel'
                        }
                       /* uploadFile: {
                              extension: 'zip,rar,doc,docx,pdf',
                              //  type:'zip,rar,doc,docx,pdf',
                                maxSize: 1024*100,
                                minSize: 1024,
                                message: '仅支持大小在1M~5M之间,类型是zip,rar,doc,docx,pdf文件!'
                        } */
                    }
                }
            }
        })
    });
        $("#uploadExcel").on("click","",function () {
            $(".recoveryNodeForm").data("bootstrapValidator").validate();
            var flag = $(".recoveryNodeForm").data("bootstrapValidator").isValid();
            alert(flag+"===========flag===========");
            if(!flag){
                //未通过验证
                return false;
            }
            var fileObj = document.getElementById("uploadFile").files[0];
            var formFile = new FormData();
            formFile.append("file", fileObj);
            var data = formFile;
            $.ajax({
                url: "budgetOaController/upload",
                data: data,
                type: "Post",
                dataType: "json",
                cache: false,//上传文件无需缓存
                processData: false,//用于对data参数进行序列化处理 这里必须false
                contentType: false, //必须
                success: function (result) {
                    console.log(JSON.stringify(result))
                    var htmlstr = '';
                    if(result.ajaxResultJson.success==false){
                        htmlstr = '<li>上传失败</li>';
                    } else {
                        htmlstr = '<li>上传成功</li>';
                    }
                    $('#exportResult').html(htmlstr);
                },
                error: function(XMLHttpRequest, textStatus, errorThrown){
                    layer.msg("系统错误",{icon: 2});
                }
            });
        });
        
        /*]]>*/
    </script>
        // 导入Excel
        @RequestMapping(value = "upload", method = RequestMethod.POST)
        public AjaxResultJson upload(MultipartFile file) {
            AjaxResultJson result = new AjaxResultJson();
            if (file == null) {
                result.setMsg("file不能为空");
                result.setObj("Excel导入失败");
                return result;
            }
            List<Budgetadjust> list = new ArrayList<>();
         String fileName = file.getOriginalFilename(); //获取文件名
    try {
          //解决You need to call a different part of POI to process this data (eg XSSF instead of HSSF)问题
          // Workbook workbook=WorkbookFactory.create(file.getInputStream()); HSSFWorkbook workbook
    = new HSSFWorkbook(new POIFSFileSystem(file.getInputStream())); // 有多少个sheet int sheets = workbook.getNumberOfSheets(); for (int i = 0; i < sheets; i++) { HSSFSheet sheet = workbook.getSheetAt(i); // 获取多少行 int rows = sheet.getPhysicalNumberOfRows(); Budgetadjust budgetadjust = null; // 遍历每一行,注意:第 0 行为标题 for (int j = 1; j < rows; j++) { budgetadjust = new Budgetadjust(); // 获得第 j 行 HSSFRow row = sheet.getRow(j); budgetadjust.setAdjustType(row.getCell(0).toString());// 调整类型 budgetadjust.setApplyDate(row.getCell(1).toString());// 申请日期 budgetadjust.setProcessCode(row.getCell(2).toString());// OA流程编号 budgetadjust.setApplyOrganization(row.getCell(3).toString());// 申请组织 budgetadjust.setApplyDepartment(row.getCell(4).toString());// 申请部门 budgetadjust.setFlag(row.getCell(5).toString());// 是否涉及人力成本 budgetadjust.setExportorganization(row.getCell(6).toString());// 调出组织 budgetadjust.setExportdepartment(row.getCell(7).toString());// 调出部门 budgetadjust.setExportsubject(row.getCell(8).toString());// 调出科目 budgetadjust.setExportmonth(row.getCell(9).toString());// 调出月份 budgetadjust.setExportmoney(row.getCell(10).toString());// 调出金额 budgetadjust.setCostControl(row.getCell(11).toString());// 查询费控系统 budgetadjust.setImportorganization(row.getCell(12).toString());// 调入组织 budgetadjust.setImportdepartment(row.getCell(13).toString());// 调入部门 budgetadjust.setImportsubject(row.getCell(14).toString());// 调入科目 budgetadjust.setImportmonth(row.getCell(15).toString());// 调入月份 budgetadjust.setImportmoney(row.getCell(16).toString());// 调入金额 budgetadjust.setAdjustreason(row.getCell(17).toString());// 调整原因 list.add(budgetadjust); } } budgetAdjustService.saveOABudget(list); } catch (IOException e) { result.setSuccess(false); result.setMsg(e.getMessage()); } result.setSuccess(true); result.setMsg("保存成功"); // 可以传文件名给页面 String fileName = file.getOriginalFilename(); //获取文件名 result.setObj(list); return result; }

    注意:

    1.要想让<input type="file">标签 能够上传多个文件,只需要在<input type="file">里添加 multiplemultiple="multiple"属性。

    2. Execl 导出锁定列和隐藏单元的值

    1.Execl列的锁定
    HSSFCellStyle style = workbook.createCellStyle();
    style.setLocked(true);//设置列的锁定状态为锁定
    2.隐藏单元格的值
    hssfRow.createCell(9).setCellValue("12月"); // 调出月
    hssfRow.createCell(20).setCellValue("A1");
    // 调出期间A1
    sheet.setColumnHidden((short)20, true); //
    隐藏第单元格20的值A1

    3.设置表头字体样式背景颜色

    private void setTitle(HSSFWorkbook workbook, HSSFSheet sheet) {
            HSSFRow row = sheet.createRow(0);
            // 设置列宽,setColumnWidth的第二个参数要乘以256,这个参数的单位是1/256个字符宽度
            sheet.setColumnWidth(8, 60 * 256);
            // 设置为居中加粗
            HSSFCellStyle style = workbook.createCellStyle();
            HSSFCellStyle style2 = workbook.createCellStyle();
            style.setLocked(true);//设置列的锁定状态
            style2.setLocked(true);
            HSSFFont font = workbook.createFont();
            HSSFFont font2 = workbook.createFont();
            font.setBold(true);//设置字体锁定状态
            style.setFont(font);
            style.setAlignment(HorizontalAlignment.CENTER);//水平居中
            style.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
            // 导出的Excel头部
            String[] headers = { "调整类型", "申请日期", "OA流程编号", "申请组织", "申请部门", "是否涉及人力成本", "调出组织", "调出部门", "调出科目", "调出月份",
                    "调出金额", "查询费控系统", "调入组织", "调入部门", "调入科目", "调入月份", "调入金额", "调整原因" };
            // 设置表格默认列宽度为15个字节
            sheet.setDefaultColumnWidth((short) 16);
            for (short i = 0; i < headers.length; i++) {
                HSSFCell cell = row.createCell(i);
                HSSFRichTextString text = new HSSFRichTextString(headers[i]);
                cell.setCellValue(text);
                if(i==10 || i>11) {
                    font2.setBold(true);
                    font2.setColor(HSSFColor.RED.index);  //颜色
                    style2.setFont(font2);
                    style2.setAlignment(HorizontalAlignment.CENTER);//水平居中
                    style2.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
                    style2.setFillPattern(FillPatternType.SOLID_FOREGROUND);
                    style2.setFillForegroundColor(IndexedColors.YELLOW.index);
                    row.getCell(i).setCellStyle(style2);
                }else {
                    cell.setCellStyle(style);
                }
            }
        }

    效果图:

    ----------------------------------------------------

    相关链接:https://blog.csdn.net/daihuimaozideren/article/details/78777656

        https://www.cnblogs.com/zhuwenxia/p/9443742.html

    文件上传链接: https://blog.csdn.net/chenxueshanBlog/article/details/78894838

    POI 3.17版本生成excel的一些样式设置:

        https://blog.csdn.net/m0_37353769/article/details/81872152

        https://blog.csdn.net/phil_jing/article/details/78307819

        获取单元格类型getCellType

        POI:https://blog.csdn.net/huasxiaopeng/article/details/42641809
        https://blog.csdn.net/jiankang66/article/details/89040742

    注意POI4.0.0版本区别

  • 相关阅读:
    面向对象的思维
    343. 整数拆分
    413. 等差数列划分
    303. 区域和检索
    62. 不同路径
    char类型与int类型相加
    mybatis里面resultmap的问题
    easyui的datagrid如何获取一个对象里面的成员对象里面的属性?
    ==和equls的区别
    泛型的使用思想
  • 原文地址:https://www.cnblogs.com/Steven5007/p/9756019.html
Copyright © 2011-2022 走看看