基于POI导出导入表格,支持复杂表格及特定要求

package com.tedu.controller;

import com.tedu.entity.Student;
import com.tedu.service.StudentService;
import com.tedu.util.Common;
import com.tedu.util.ResponseObj;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * TODO
 *
 * @author syl
 */
@RestController
@RequestMapping("/")
@Api("测试导入导出")
@Slf4j
public class ExportImportController {
    /**
     * 日志
     */
    public static final Logger LOG= LoggerFactory.getLogger(ExportImportController.class);



    @Autowired
    private StudentService studentService;

    private  List<String> list;

    @RequestMapping(value = "importData",method = RequestMethod.POST)
    @ApiOperation("导入数据")
    public ResponseObj<Void> importData(@RequestParam MultipartFile file) throws IOException {
        //获取输入流
        InputStream in = file.getInputStream();
        //校验文件格式
        String filename = file.getOriginalFilename();
        String suffix = filename.substring(filename.lastIndexOf("."));
        Workbook work;
        if(Common.Excel.EXCEL_2003.equals(suffix) ){
            work=new HSSFWorkbook(in);
        }else if(Common.Excel.EXCEL_2007.equals(suffix)){
            work=new XSSFWorkbook(in);
        }else {
            log.error("文件格式不对");
            return ResponseObj.fail("500","文件格式不对");
        }
        //关闭流
        in.close();

        //解析表格
        List<List<String>> liAll = parseExcel(work);

        //List<String>转成List<Student>
        List<Student> list=new ArrayList<>();
        for(int i=Common.Number.ZERO;i<liAll.size();i++){
            Student student=new Student();
            List<String> stu = liAll.get(i);
            student.setSno((stu.get(Common.Number.ZERO)));
            student.setClass1((stu.get(Common.Number.ONE)));
            student.setName((stu.get(Common.Number.TWO)));
            student.setSex((stu.get(Common.Number.THREE)));
            student.setChinese((stu.get(Common.Number.FOUR)));
            student.setMath((stu.get(Common.Number.FIVE)));
            student.setEnglish((stu.get(Common.Number.SIX)));
            list.add(student);
        }
        //调用批量新增方法
        int success= studentService.insert(list);
        return ResponseObj.success("200", "成功新增"+success+"行");
    }

    /**
     * 解析表格
     * @param work
     * @return
     */
    private List<List<String>> parseExcel(Workbook work) {
        //表
        Sheet sheet;
        //行
        Row row;
        //单元格
        Cell cell;
        //总行数
        int rowCount;
        //存放导入的数据
        List<List<String>> liAll=new ArrayList<>();
        for (int i = Common.Number.ZERO; i<work.getNumberOfSheets(); i++){
            //获取每一个表
            sheet=work.getSheetAt(i);
            if(sheet==null){
                continue;
            }
            rowCount=sheet.getPhysicalNumberOfRows();
            //获取表中数据
            for (int j=sheet.getFirstRowNum()+Common.Number.TWO;j<rowCount;j++){
                row = sheet.getRow(j);
                if(!isEmptyRow(row)){
                    //存放每行数据
                    List<String> li=new ArrayList<>();
                    for (int k=row.getFirstCellNum(); k <row.getLastCellNum();k++){
                        cell = row.getCell(k);
                        String value= getCellValue(cell).toString();
                        li.add(value);
                    }
                    liAll.add(li);
                }
                else if(isEmptyRow(row)){
                    continue;
                }
            }
        }
        return liAll;
    }

    /**
     * 判断是否为空行
     * @param row
     * @return
     */
    private boolean isEmptyRow(Row row) {
        Cell cell;
        for (int i=row.getFirstCellNum();i<row.getLastCellNum();i++){
            cell=row.getCell(i);
            if (cell!=null && !cell.getCellTypeEnum().equals(CellType.BLANK)){
                return false;
            }
        }
        return true;
    }

    /**
     * 描述:对表格中数值进行格式化
     *
     * @param cell
     *
     * @return
     */
    public Object getCellValue(Cell cell) {
        String result = new String();
        switch (cell.getCellType()) {
            //Excel公式
            case FORMULA:
                try {
                    result = String.valueOf(cell.getNumericCellValue());
                } catch (IllegalStateException e) {
                    result = String.valueOf(cell.getRichStringCellValue());
                }
                break;
            // 数字类型
            case NUMERIC:
                // 处理日期格式、时间格式
                if (HSSFDateUtil.isCellDateFormatted(cell)) {
                    SimpleDateFormat sdf;
                    if (cell.getCellStyle().getDataFormat() == HSSFDataFormat
                            .getBuiltinFormat("h:mm")) {
                        sdf = new SimpleDateFormat("HH:mm");
                    } else {// 日期
                        sdf = new SimpleDateFormat("yyyy-MM-dd");
                    }
                    Date date = cell.getDateCellValue();
                    result = sdf.format(date);
                } else if (cell.getCellStyle().getDataFormat() == 58) {
                    // 处理自定义日期格式:m月d日(通过判断单元格的格式id解决,id的值是58)
                    SimpleDateFormat sdf = new SimpleDateFormat("M月d日");
                    double value = cell.getNumericCellValue();
                    Date date = org.apache.poi.ss.usermodel.DateUtil
                            .getJavaDate(value);
                    result = sdf.format(date);
                } else {
                    double value = cell.getNumericCellValue();
                    CellStyle style = cell.getCellStyle();
                    DecimalFormat format = new DecimalFormat();
                    String temp = style.getDataFormatString();
                    // 单元格设置成常规
                    if (temp.equals("General")) {
                        format.applyPattern("#.##");
                    }
                    result = format.format(value);
                }
                break;
            // String类型
            case STRING:
                result = cell.getRichStringCellValue().toString();
                break;
            case BLANK:
                result = "";
            default:
                result = "";
                break;
        }
        return result;
    }

    public String getFormat(String str) {
        if(str.equals("null")) {
            str="";
            return str;
        }else{
            return str;
        }
    }
    public Integer getFormats(Integer str) {
        if(str==null) {
            str=0;
            return str;
        }else{
            return str;
        }
    }

    /**
     * 获取字符串中的数字订单号、数字金额等,如从"USD 374.69"中获取到374.69、从“交易单号:123456789”获取到123456789
     *
     * @return
     */
    public static String getFormatNumber(String str){
        str = str.trim();
        Pattern p = Pattern.compile("[0-9]");
        int indexNum = 0;
        int lenght = str.length();
        String num = "";
        for(int i=0;i<lenght;i++){
            num += str.charAt(i);
            Matcher m = p.matcher(num);
            if(m.find()){
                indexNum = i;
                break;
            }
        }
        String formatNumber = str.substring(indexNum,lenght);
        return formatNumber;
    }


    /**
     * 导出
     * @param response
     * @throws Exception
     * @apiNote 输出到网页必须在 @RequestMapping添加produces = "application/octet-stream",不然表格导出异常
     */
    @RequestMapping(value = "exportData", method = RequestMethod.POST,produces = "application/octet-stream")
    @ApiOperation("导出数据")
    public void  exportData(HttpServletResponse response){
        inti();
        //创建工作簿
        XSSFWorkbook wk=new XSSFWorkbook();
        //创建表
        XSSFSheet sheet = wk.createSheet("zyp");
        //设置首行
        setFirstRow(sheet,wk);
        //设置第二行
        setSecondRow(sheet,wk);
        //设置主体
        setBody(sheet,wk);
        //输出到磁盘
        //OutputStream out= new BufferedOutputStream(new FileOutputStream("H://zyp.xlsx"));
        OutputStream out= null;
        try {
            out = response.getOutputStream();
            //输出到网页
            response.reset();
            response.setContentType("application/octet-stream; charset=utf-8");
            response.setHeader("Content-Disposition", "attachment; filename=student.xlsx");
            wk.write(out);
            out.flush();
        } catch (IOException e) {
            log.error(e.getMessage());
        }finally {
            //保证输出流关闭
            try {
                if (out!=null){
                    out.close();
                }
            } catch (IOException e) {
                log.error(e.getMessage());
            }
        }


    }

    /**
     * 设置首行
     * @param sheet
     * @param wk
     */
    private void setFirstRow(XSSFSheet sheet,XSSFWorkbook wk){
        XSSFCellStyle cellStyle=setCellStyle(wk, Common.Number.ZERO, Common.Number.ONE_NEGATIVE);
        //合并单元格
        sheet.addMergedRegion(new CellRangeAddress(Common.Number.ZERO, Common.Number.ZERO, Common.Number.ZERO, Common.Number.EIGHT));
        XSSFRow row_0 = sheet.createRow(Common.Number.ZERO);
        row_0.setHeightInPoints(Common.Number.FOURTH);
        XSSFCell cell_0 = row_0.createCell(Common.Number.ZERO);
        cell_0.setCellValue("学生成绩表");
        cell_0.setCellStyle(cellStyle);
    }

    /**
     * 设置第二行
     * @param sheet
     * @param wk
     */
    private void setSecondRow(XSSFSheet sheet, XSSFWorkbook wk){
        XSSFRow row_1 = sheet.createRow(Common.Number.ONE);
        //设置指定行高
        row_1.setHeightInPoints(Common.Number.TWENTY_FIVE);
        XSSFCell cell;
        XSSFCellStyle cellStyle;
        for(int i = Common.Number.ZERO;i <list.size();i++){
            cell=row_1.createCell(i);
            cell.setCellValue(list.get(i));
            cellStyle=setCellStyle(wk,Common.Number.ONE,Common.Number.ONE_NEGATIVE);
            cell.setCellStyle(cellStyle);
        }
    }

    /**
     * 设置主体
     * @param sheet
     * @param wk
     * @throws Exception
     */
    private void setBody(XSSFSheet sheet, XSSFWorkbook wk){
        List<Student> records = studentService.findAll(new Student(), Common.Number.ONE, Common.Number.ONE_HUNDERD).getRecords();
        XSSFRow row;
        XSSFCell cell;
        XSSFCellStyle style;
        List<String> stuList;
        int total;
        for (int i=Common.Number.ZERO;i<records.size();i++){
            row = sheet.createRow(i + Common.Number.TWO);
            row.setHeightInPoints(Common.Number.FIFTEEN);
            for (int j=Common.Number.ZERO;j<list.size();j++){
                cell = row.createCell(j);
                stuList=getDetails(records.get(i));
                cell.setCellValue(stuList.get(j));
                //三门成绩大于240为优秀
                total=Integer.parseInt(stuList.get(Common.Number.FOUR))+Integer.parseInt(stuList.get(Common.Number.FIVE))+Integer.parseInt(stuList.get(Common.Number.SIX));
                if (total>=Common.Number.TWO_HUNDRED_AND_FORTY){
                    style= setCellStyle(wk, i+Common.Number.TWO,Common.Number.ONE_NEGATIVE);
                    cell.setCellStyle(style);
                }else {
                    style= setCellStyle(wk, i+Common.Number.TWO,Common.Number.ZERO);
                    cell.setCellStyle(style);
                }
                //忽略数字转文本错误
                sheet.addIgnoredErrors(new CellReference(cell),IgnoredErrorType.NUMBER_STORED_AS_TEXT);
                //设置指定列宽
                sheet.setColumnWidth(Common.Number.SEVEN, Common.Number.TWENTY_FIVE * Common.Number.TWO_HUNDRED_AND_FIFTY_SIX);
                sheet.setColumnWidth(Common.Number.EIGHT,Common.Number.TWENTY_FIVE * Common.Number.TWO_HUNDRED_AND_FIFTY_SIX);
            }
        }
    }


    private List<String> getDetails(Student s) {
        List<String> list=new ArrayList<>();
        list.add(s.getSno());
        list.add(s.getClass1());
        list.add(s.getName());
        list.add(s.getSex());
        list.add(s.getChinese());
        list.add(s.getMath());
        list.add(s.getEnglish());
        list.add(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(s.getCreateTime()));
        list.add(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(s.getUpdateTime()));
        return list;
    }


    /**
     * 设置样式
     * @param workbook
     * @param rowId -1表示全部
     * @param columnId -1表示全部
     */
    private XSSFCellStyle setCellStyle(XSSFWorkbook workbook,int rowId,int columnId){
        XSSFCellStyle cellStyle = workbook.createCellStyle();
        //水平居中
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        //垂直居中
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        //上边框
        cellStyle.setBorderTop(BorderStyle.THIN);
        //下边框
        cellStyle.setBorderBottom(BorderStyle.THIN);
        //左边框
        cellStyle.setBorderLeft(BorderStyle.THIN);
        //右边框
        cellStyle.setBorderRight(BorderStyle.THIN);
        //设置字体
        XSSFFont font = workbook.createFont();
        font.setFontName("宋体");
        //设置样式
        cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        //设置首行样式
        if (rowId==Common.Number.ZERO && columnId==Common.Number.ONE_NEGATIVE){
            //设置背景
            cellStyle.setFillForegroundColor(IndexedColors.BLUE.getIndex());
            font.setBold(true);
        }
        //设置第二行样式
        if (rowId==Common.Number.ONE && columnId==Common.Number.ONE_NEGATIVE) {
            //设置背景
            cellStyle.setFillForegroundColor(IndexedColors.ORANGE.getIndex());
            font.setBold(true);
        }
        //设置主体样式
        if (rowId>Common.Number.ONE && columnId==Common.Number.ONE_NEGATIVE){
            //设置背景
            cellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
        }else if(rowId>Common.Number.ONE && columnId==Common.Number.ZERO){
            cellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        }
        cellStyle.setFont(font);
        //设置自动换行
        cellStyle.setWrapText(true);
        return cellStyle;
    }

    private void inti() {
        list = new ArrayList<>();
        list.add("学号");
        list.add("班级");
        list.add("姓名");
        list.add("性别");
        list.add("语文");
        list.add("数学");
        list.add("英语");
        list.add("创建时间");
        list.add("修改时间");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值