导入EXcel工具类

一、概述

在工作过程中,都会遇到这样一个需求,就是将相关的Excel中的数据导入数据库,这里写成通用的导入Excel的工具。

二、项目实现

1、构建pom.xml

我的工程是利用Maven来构建的,这里仅给出最核心的包

<dependency>
    <groupId>commons-lang</groupId>
    <artifactId>commons-lang</artifactId>
    <version>2.6</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-scratchpad</artifactId>
    <version>3.11-beta2</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.11-beta2</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml-schemas</artifactId>
    <version>3.11-beta2</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-excelant</artifactId>
    <version>3.11-beta2</version>
</dependency>
<!-- excel上传用 -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>

导入之前需要先下载要导入的Excel模板,把数据填写到Excel,然后在导入到数据库中

2.下载Excelm模板通用工具类

/**
     *
     *          2003导出下载Excel模板
     * @param fileName    文件名
     * @param titles      导出excel标题
     * @param hashMapKeys 导出excel显示的列头(对应pojo里面的属性)
     * @Description: 2003版本最大支持65536行
     */
    public static void exportExcelTemplate(String fileName, String[] titles, String[] hashMapKeys,HttpServletResponse response) throws IOException{
        // 1.创建工作簿
        HSSFWorkbook workbook = new HSSFWorkbook();
        // 2.在workbook中添加一个sheet,对应Excel文件中的fileName
        HSSFSheet sheet = workbook.createSheet(fileName);

        // 样式1:定义列宽
        for (int i = 0; i < 100; i++) {
            sheet.setColumnWidth(i, 6000);
        }

        //基础样式
        HSSFCellStyle baseStyle = workbook.createCellStyle();
        //设置单元格居中
        baseStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 左右居中
        baseStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 上下居中

        //设置边框
        baseStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);  //下边框
        baseStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);    //左边框
        baseStyle.setBorderTop(HSSFColor.BLACK.index); //上边框
        baseStyle.setBorderRight(HSSFColor.WHITE.index); //右边框
        //设置自动换行
        baseStyle.setWrapText(true);

        //样式2:定义第一行单元格样式
        HSSFCellStyle cellStyle = workbook.createCellStyle();
        //设置字体
        HSSFFont font = workbook.createFont();
        font.setFontName("宋体");
        font.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
        // 字体大小
        font.setFontHeightInPoints((short) 12);
        cellStyle.setFont(font);
        //设置单元格居中
        cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

        //样式3:定义标题单元格样式
        HSSFCellStyle cellStyle1 = workbook.createCellStyle();
        cellStyle1.cloneStyleFrom(baseStyle);
        //设置字体
        HSSFFont font1 = workbook.createFont();
        font1.setFontName("楷体");
        font1.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        font1.setFontHeightInPoints((short) 12);// 字体大小
        font1.setColor(HSSFColor.RED.index);//设置红色
        cellStyle1.setFont(font1);
        //设置背景色
        cellStyle1.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
        cellStyle1.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());

        //样式4:定义内容栏单元格样式
        HSSFCellStyle cellStyle2 = workbook.createCellStyle();
        cellStyle2.cloneStyleFrom(baseStyle);
        //设置字体
        HSSFFont font2 = workbook.createFont();
        font2.setFontName("宋体");
        font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
        // 字体大小
        font2.setFontHeightInPoints((short) 12);
        cellStyle2.setFont(font2);
        //设置单元格居左和居上
        HSSFDataFormat format=workbook.createDataFormat();
        cellStyle2.setDataFormat(format.getFormat("@"));

        //样式5:定义尾部栏注释单元格样式
        HSSFCellStyle cellStyle3 = workbook.createCellStyle();
        HSSFFont font3 = workbook.createFont();
        font3.setFontName("楷体");
        font3.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        font3.setFontHeightInPoints((short) 12);// 字体大小
        font3.setColor(HSSFColor.RED.index);//设置红色
        cellStyle3.setFont(font3);
        //样式6:合并第一行单元格
//        Region region1 = new Region(0, (short) 0, 0, (short) (titles.length - 1));
//        sheet.addMergedRegion(region1);
        //2.创建顶行
        HSSFRow rowhead = sheet.createRow(0);
        rowhead.setHeight((short) 700);
        HSSFCell cellhead = rowhead.createCell(0);
        cellhead.setCellValue(fileName.substring(0, fileName.lastIndexOf(".")));
        cellhead.setCellStyle(cellStyle);

        //3.创建标题行
        HSSFRow row = sheet.createRow(0);
        // row.setHeight((short) 550);
        for (int i = 0; i < titles.length; i++) {
            HSSFCell cell = row.createCell(i);
            cell.setCellValue(titles[i]);
            cell.setCellStyle(cellStyle1);
        }
        //4.创建key行
        HSSFRow rowi=sheet.createRow(2);
        for (int i = 0; i <  hashMapKeys.length; i++) {
            HSSFCell cell = rowi.createCell(i);
            cell.setCellValue(hashMapKeys[i]);
            cell.setCellStyle(cellStyle1);
        }
        HSSFRow row3=sheet.createRow(3);
        for (int i = 0; i <  hashMapKeys.length; i++) {
            HSSFCell cell = row3.createCell(i);

            cell.setCellStyle(cellStyle2);
        }
        //6.输出到Excel表格
        //设置响应头
        if (fileName.endsWith("xlsx")) {
            // response.setContentType("application/vnd.ms-excel");
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        } else {
            response.setContentType("application/vnd.ms-excel");
        }
        response.setHeader("Content-disposition", "attachment; fileName=" + URLEncoder.encode(fileName, "UTF-8"));
        OutputStream out = response.getOutputStream();
        workbook.write(out);
//            out.flush();
//            out.close();

    }

3.下载Excel模板Controller

import com.htf.utils.ExcelUtils;
import com.htf.utils.ImportExcelUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.*;
@Controller
public class ExportExcelController {
public static final String[] KEYS = {"id", "name", "age"};

/**
 * @param : [map, response]
 * @return : void
 * @date : 2018/10/27 16:08
 * @exception:
 * @Description: 下载excel2003模板测试  
 */
@RequestMapping("/downloadTemplate.do")
public void downTemplate(@RequestParam HashMap<String, Object> map, HttpServletResponse response) {
    List<Map> list = new ArrayList<>();
    //必填字段
    String[] key = ExportExcelController.KEYS;
    String[] titles = new String[]{"名称", "性别", "年龄", "学校", "班级"};
    String fileName = "报表.xls";
    try {
        ExcelUtils.exportExcelTemplate(fileName, key, titles, response);
        response.getOutputStream().close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

4.测试下载Excel模板

模板内容如下图

5.导入Excel工具类

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.File;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ImportExcelUtils {
/**
 *          导入excel
 * @param : file        文件
 * @param : startRow    起始行
 * @param : startColumn 起始列
 * @param : endRow
 * @param : endColumn
 * @return : java.util.List<java.lang.String[]>
 * @date : 2018/10/27 16:15
 * @exception:
 * @Description: 解析excel表XSSF  List<String[]>,适用于2007挤以上版本的excel,后缀名为.xlsx或.xls文件
 * 默认解析工作簿中的第一张表,如果endRow=-1则默认解析最后一行,如果endColumn=-1则默认解析到startRow行的最后一列,后面的空行也会解析
 * 输入的4个参数第几行和第几列都是从1算起,都是字面上的行或列,解析excel时会将所以单元格的类型转化为String类型,没有值的单元格默认值为"",
 * 没有任何值的空行会跳过处理
 */
public static List<String[]> importExcel(File file, int startRow, int startColumn, int endRow, int endColumn) throws Exception {
    try {
        //导入excel文件,获取工作簿
        Workbook workbook = WorkbookFactory.create(file);
        //获取excel工作表对象,默认去第一个
        Sheet sheet = workbook.getSheetAt(0);
        //设置默认值,行数从0算起的,列数从1算起的
        if (endRow == -1) endRow = sheet.getLastRowNum() + 1;
        if (endColumn == -1) endColumn = sheet.getRow(startRow - 1).getLastCellNum();
        //定义集合
        List<String[]> list = new ArrayList<>();
        //给集合中添加数据
        for (int i = startRow - 1; i < endRow; i++) {
            Row r = sheet.getRow(i);
            if (null == r) continue;
            String[] strArr = new String[endColumn - startColumn + 1];
            for (int j = startColumn - 1; j < endColumn; j++) {
                //转化单元格的类型为String类型
                if (null != r.getCell(j)) {
                    r.getCell(j).setCellType(Cell.CELL_TYPE_STRING);
                    strArr[j] = r.getCell(j).getStringCellValue();
                    continue;
                }
                strArr[j] = "";
            }
            list.add(strArr);
        }
        return list;
    } catch (Exception e) {
        throw new Exception(e.getMessage());
    }
}

6.导入Excel Controller代码

import com.htf.service.ExportExcelService;
import com.htf.utils.ExcelUtils;
import com.htf.utils.ImportExcelUtils;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * @Auther: admin
 * @Date: 2018/10/1 21:18
 * @Description:上传Excel
 */
@Controller
public class ExportExcelController {
    /** 
    * @date   : 2018/10/28 11:22   
    * @param  : [request, file, response] 
    * @return : java.lang.String 
    * @exception:
    * @Description: 导入Excel
    * 
    */  
    @RequestMapping("/importExcel.do")
    public String importExcel(HttpServletRequest request, @RequestParam("file") CommonsMultipartFile file, HttpServletResponse response) {
        StringBuffer buffer = new StringBuffer();
        //根据指定类的相对路径来查找
        Resource resource = new ClassPathResource("../exportTemplate", this.getClass());
        String name = file.getOriginalFilename();
        //只能上传.xls后缀的文件
        if (!name.endsWith(".xls") && !name.endsWith(".xlsx")) {
            buffer.append("必须使用下载模板上传");
        }
        try {
            if (!resource.exists()) {
                resource.getFile().mkdir();
            }
            File fileExcel = new File(resource.getFile().getPath() + "/" + name);
            file.getFileItem().write(fileExcel);
            //解析文件
            List<String[]> list = ImportExcelUtils.importExcel(fileExcel, 1, 1, -1, -1);
            //定义信息结果字符串
            //定义上传成功计数器
            int count = 0;
            //对解析的模板进行校验
            //1.校验模板是否正确
            if (!("类型".equals(list.get(0)[0]) && "数据".equals(list.get(0)[1]))) {
                buffer.append("您的模板不正确,第一行第一格必须是类型,第二行第二格必须是数据!!!");
            }
            //校验是否为XSS代码
//            for (int i = 1; i < list.size(); i++) {
//                if (XssInterceptor.matches(list.get(i)[1])) {
//                    buffer.append("该模板里存在恶意代码,请检查后重新上传");
//                }
//            }
            if (list.size() == 0) {
                buffer.append("模板数据为空");
            }
            for (int i = 1; i < list.size(); i++) {
                //校验为空的单元格
                if (StringUtils.isBlank(list.get(i)[0]) || StringUtils.isBlank(list.get(i)[1])) {
                    buffer.append("第" + (i + 1) + "行数据为空,不能正确导入");
                    continue;
                }
                //2.校验单元格长度大于100字符
                if (list.get(i)[1].length() >= 100) {
                    buffer.append("第" + (i + 1) + "行导入的字符数超过100字,不能正确导入");
                    continue;
                }
                //4.校验数据是否重复
                HashMap map = new HashMap();
                map.put("id", list.get(i)[0]);
                map.put("name", list.get(i)[1]);
                continue;
            }
            //5存入数据库
            HashMap hashMap = new HashMap();
            hashMap.put("id", "");

            //存入数据库,调用service里面的方法插入,(传入参数是hashMap)
            // excelService.insert(hashMap);
            if (count == 0) {
                buffer.append("模板数据全部为已导入的重复数据!");

            } else {
                buffer.append("共存入" + count + "条数据!");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "xxx页面";
    }
}

7.校验是否为XSS,需要实现 HandlerInterceptor接口

猜你喜欢

转载自blog.csdn.net/qq_40428665/article/details/83473192