一篇完整的Java实现excel导入导出(包含前端页面)

1.开发环境

后台用springboot
前台纯html+js

2.工程导入pom

        
        <dependency>
            <groupId>org.apache.poigroupId>
            <artifactId>poiartifactId>
            <version>3.16version>
        dependency>
        <dependency>
            <groupId>org.apache.poigroupId>
            <artifactId>poi-ooxmlartifactId>
            <version>3.16version>
        dependency>
        

3.写后端工具类

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.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;

/**
 * excel工具类
 */
public class ExcelUtil {
    /**
     * 将Excel内容转换list
     * @param file
     * @param name
     * @return
     * @throws Exception
     */
    public static List<Map<String, Object>> excelToList(MultipartFile file, String name) throws Exception {
        Workbook workbook = WorkbookFactory.create(file.getInputStream());
        Sheet sheet = workbook.getSheet(name);
        //行数
        int num = sheet.getLastRowNum();
        //列数
        int col = sheet.getRow(0).getLastCellNum();
        List<Map<String, Object>> list = new ArrayList<>();
        String[] colName = new String[col];
        //获取列名
        Row row = sheet.getRow(0);
        for (int i = 0; i < col; i++) {
            String[] s = row.getCell(i).getStringCellValue().split("-");
            colName[i] = s[0];
        }

        //将一行中每列数据放入一个map中,然后把map放入list
        for (int i = 1; i <= num; i++) {
            Map<String, Object> map = new HashMap<>();
            Row row1 = sheet.getRow(i);
            if (row1 != null) {
                for (int j = 0; j < col; j++) {
                    Cell cell = row1.getCell(j);
                    if (cell != null) {
                        cell.setCellType(Cell.CELL_TYPE_STRING);
                        map.put(colName[j], cell.getStringCellValue());
                    }
                }
            }
            list.add(map);
        }
        return list;
    }

    /**
     * 导出集合到excel
     * @param response
     * @param name
     * @param list
     */
    public static void exportToExcel(HttpServletResponse response, String name, List<LinkedHashMap<String, Object>> list) {
        try {
            //文件名称
            String fileName = name + ".xls";
            HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
            HSSFSheet hssfSheet = hssfWorkbook.createSheet(name);
            int rowNum = 0;
            //新建行
            HSSFRow hssfRow = hssfSheet.createRow(rowNum++);
            //列
            int j = 0;
            if (list.size() > 0) {
                for (String i : list.get(0).keySet()) {
                    //新建第一行
                    hssfRow.createCell(j++).setCellValue(i);
                }
                //将数据放入表中
                for (int i = 0; i < list.size(); i++) {
                    //新建一行
                    HSSFRow row = hssfSheet.createRow(rowNum++);
                    Map map = list.get(i);
                    System.out.println(map);
                    j = 0;
                    for (Object obj : map.values()) {
                        if (obj != null) {
                            row.createCell(j++).setCellValue(obj.toString());
                        } else {
                            row.createCell(j++);
                        }
                    }
                }
            }
            // 告诉浏览器用什么软件可以打开此文件
            response.setHeader("content-Type", "application/vnd.ms-excel");
            // 下载文件的默认名称
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8"));
            hssfWorkbook.write(response.getOutputStream());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /***
     * 解析Excel日期格式
     * @param strDate
     * @return
     */
    public static String ExcelDoubleToDate(String strDate) {
        if (strDate.length() == 5) {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date tDate = DoubleToDate(Double.parseDouble(strDate));
                return sdf.format(tDate);
            } catch (Exception e) {
                e.printStackTrace();
                return strDate;
            }
        }
        return strDate;
    }

    /**
     * 解析Excel日期格式
     * @param dVal
     * @return
     */
    public static Date DoubleToDate(Double dVal) {
        Date tDate = new Date();
        //系统时区偏移 1900/1/1 到 1970/1/1 的 25569 天
        long localOffset = tDate.getTimezoneOffset() * 60000;
        tDate.setTime((long) ((dVal - 25569) * 24 * 3600 * 1000 + localOffset));
        return tDate;
    }
}

直接拿去贴

4.导出查询结果到excel

1.写后端controller

    /**
     * 导出excel
     * @return
     */
    @RequestMapping("/exportMonitor")
    @ResponseBody
    public void exportMonitor(String monitorName,String monitorState,String monitorOccupyState,String monitorSwitchState ,String significant, HttpServletResponse response){
        Map<String,Object> param=new HashMap<String, Object>(8);
        param.put("monitorName",monitorName);
        param.put("monitorState",monitorState);
        param.put("monitorOccupyState",monitorOccupyState);
        param.put("monitorSwitchState",monitorSwitchState);
        param.put("significant",significant);
        List<LinkedHashMap<String,Object>> database=monitorService.getAllMonitorLinkedHashMap(param);
        ExcelUtil.exportToExcel(response,"monitor",database);
        //return ResultObj.returnObj(DatabaseUtil.returnDatabaseNoResult(true,"导出成功"));
    }

注意,这里要用get形式,因为前台的地址是拼接起来的,这点很重要,看下面就知道了

2.写前端js

Monitor.export=function(){
    let export1 = document.getElementById('export');
    //字符串拼接,不然传的就是'undefined',真的是这个字符串传过去
    let params ='';
    if($("#monitorName").val()){
        params+='&monitorName';
    }
    if($("#monitorState").val()){
        params+='&monitorState';
    }
    if($("#monitorOccupyState").val()){
        params+='&monitorOccupyState';
    }
    if($("#monitorSwitchState").val()){
        params+='&monitorSwitchState';
    }
    if($("#significant").val()){
        params+='&significant';
    }
	//截取前面的&
  export1.setAttribute('href',"/monitor/exportMonitor?"+params.substring(1,params.length));
}

这个export是关键字,不能用,懒得改名了,加了个1

3.写前端html

     <a id="export" >
         <button type="button" class="btn btn-primary " onclick="Monitor.export()" id="importMonitor">
             <i class="fa fa-search">i> 导出
         button>
     a>

导出按钮,用a标签括起来,这里利用js的冒泡事件,js点击这个button,然后调用上面js的函数,这个函数改变这个a标签t的地址,函数执行完成之后,向上冒泡,相当于点击了a标签,a标签跳转后台页面。

4.总结

之前用过ajax执行,然后他返回的response里有一个xls的文件,这里已经改好了,我的就不回退回去了,借用别的老哥两张图
一篇完整的Java实现excel导入导出(包含前端页面)_第1张图片
一篇完整的Java实现excel导入导出(包含前端页面)_第2张图片
出自https://blog.csdn.net/jinchunzhao123/article/details/88626077
我的response跟他类似,这是我的后台
一篇完整的Java实现excel导入导出(包含前端页面)_第3张图片
只有展示,浏览器没有自动下载
之后将这个地址放在a标签里,使用herf跳转就完事了

5.导入excel到数据库

1.写后端controller

    /**
     * 导入excel
     * @param file
     * @return
     */
    @RequestMapping("/importMonitor")
    @ResponseBody
    public Object importMonitor(@RequestParam MultipartFile file){
        Map<String,Object> database=monitorService.importMonitor(file);
        return ResultObj.returnObj(database);
    }

2.写service

    @Override
    public Map<String, Object> importMonitor(MultipartFile file) {
        Map<String,Object> param=new HashMap<String, Object>(8);
        try {
            List<Map<String,Object>> importList= ExcelUtil.excelToList(file,excelSelect);
            for (Map<String,Object> importMap: importList) {
                String id= OddNumbersUtil.getNumber("monitor");
                param.put("id",id);
                param.put("monitorName",importMap.get("monitor_name"));
                param.put("monitorNumebr",importMap.get("monitor_numebr"));
                param.put("ip",importMap.get("ip"));
                param.put("port",importMap.get("port"));
                param.put("monitorState",1);
                param.put("monitorOccupyState",1);
                param.put("createTime",new Date());
                param.put("createPerson",ShiroKit.getUser().name);
                //param.put("updateTime",importMap.get("update_time"));
                //param.put("updatePerson",importMap.get("update_person"));
                param.put("imgUrl",importMap.get("img_url"));
                param.put("contacts",importMap.get("contacts"));
                param.put("contactNumber",importMap.get("contact_number"));
                param.put("installDate",ExcelUtil.ExcelDoubleToDate(String.valueOf(importMap.get("install_date"))));
                param.put("periodOfValidity",ExcelUtil.ExcelDoubleToDate(String.valueOf(importMap.get("period_of_validity"))));
                param.put("expirationDate",ExcelUtil.ExcelDoubleToDate(String.valueOf(importMap.get("expiration_date"))));
                param.put("deviceAddress",importMap.get("device_address"));
                param.put("monitorSwitchState",1);
                param.put("deviceType",importMap.get("device_type"));
                param.put("modelType",importMap.get("model_type"));
                param.put("significant",importMap.get("significant"));
                param.put("locational",importMap.get("locational"));
                param.put("manufacturersId",importMap.get("manufacturers_id"));
                param.put("deviceCoding",importMap.get("device_coding"));
                param.put("subordinateSubsystem",importMap.get("subordinate_subsystem"));
                monitorMapper.addMonitor(param);
            }
            return DatabaseUtil.returnDatabaseNoResult(true,"导入成功");
        } catch (Exception e) {
            e.printStackTrace();
            return DatabaseUtil.returnDatabaseNoResult(true,"导入失败");
        }
    }

这里略过接口,直接看实现类,里面有的地方用了ExcelUtil.ExcelDoubleToDate()函数,是因为excel读取的日期是一个数字,用这个函数可以转为规定的日期格式,这个函数详见上面的工具类

2.写前端js

方式1

    layui.use('upload', function(){
        var upload = layui.upload;
        //执行实例
        var uploadInst = upload.render({
            elem: '#importMonitor' //绑定元素
            ,url: 'monitor/importMonitor' //上传接口
            ,accept: 'file'
            ,exts: 'xls|xlsx|xlsm|xlt|xltx|xltm'
            ,done: function(res){
                if(res.success){
                    layer.msg('导入成功');
                    stockRecord.table.refresh();
                }else{
                    layer.msg(res.message());
                }
                //上传完毕回调
            }
            ,error: function(){
                //请求异常回调
            }
        });
    });

这是layui的上传文件,今天向同事学的,推荐使用这个,比较方便

3.写前端html

<#button name="导入excel" icon="fa" id="importMonitor"/>

前台只要有一个元素承接就行了

你可能感兴趣的:(javascript,poi,java)