java实现excel的导入导出

泄露秘密 提交于 2020-02-28 17:07:36

日常开发中,对于excel的导入导出的需求必不可少。在此整理一下

一、导入

1.maven导入

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

2.添加Excel类

package com.ydwl.business.campus.common.utils;


import org.apache.poi.ss.usermodel.*;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

public class Excel {

    public enum Type {
        XLS(".xls"),
        XLSX(".xlsx");

        private String suffix;

        Type(String suffix) {
            this.suffix = suffix;
        }

        public String getSuffix() {
            return suffix;
        }

    }

    private Type type;
    private Workbook workBook;
    private Sheet sheet;

    Excel(Workbook workBook, Type type) {
        this.type = type;
        this.workBook = workBook;
    }

    public Workbook getWorkbook() {
        return workBook;
    }

    public String getSuffix() {
        return type.getSuffix();
    }

    public Integer getLastRowNum() {
        // get the last row number on the now select sheet
        // based 0, contained n
        return currentSheet().getLastRowNum();
    }

    public Excel createSheet() {
        this.sheet = workBook.createSheet();
        return this;
    }

    public Excel createSheet(String sheetname) {
        this.sheet = workBook.createSheet(sheetname);
        return this;
    }

    public Excel selectSheet(int index) {
        this.sheet = workBook.getSheetAt(index);
        return this;
    }

    public Excel selectSheet(String sheetname) {
        this.sheet = workBook.getSheet(sheetname);
        return this;
    }

    public Sheet currentSheet() {
        if (sheet == null) {
            throw new RuntimeException("Create or select sheet first.");
        }
        return sheet;
    }

    public List<?> readRow(Integer rowNum) {
        Row row = currentSheet().getRow(rowNum);
        if (row == null) {
            return new ArrayList<>();
        }
        return readRow(rowNum, 0, (int) row.getLastCellNum());
    }

    public List<?> readRow(Integer rowNum, Integer colNum) {
        // get 0 to colNum cell (not contain colNum)
        return readRow(rowNum, 0, colNum);
    }

    public List<?> readRow(Integer rowNum, Integer firstCellNum, Integer lastCellNum) {
        // get now select sheet a line, rowNum begin 0
        // firstCellNum begin 0, not contain lastCellNum
        List<Object> rowContent = new ArrayList<>();
        Row row = currentSheet().getRow(rowNum);
        for (int i = firstCellNum; i < lastCellNum; i++) {
            rowContent.add(getCellValue(row.getCell(i)));
        }
        return rowContent;
    }

    public Excel writeRow(Integer rowNum, List<?> rowContent) {
        int len = rowContent.size();
        Row row = currentSheet().createRow(rowNum);
        for (int i = 0; i < len; ++i) {
            setCellValue(row.createCell(i), rowContent.get(i));
        }
        return this;
    }

    public Excel write(OutputStream out) throws IOException {
        workBook.write(out);
        out.flush();
        return this;
    }

    private Object getCellValue(Cell cell) {
        Object cellValue = "";
        if (cell != null) {
            switch (cell.getCellType()) {
                case Cell.CELL_TYPE_NUMERIC:
                case Cell.CELL_TYPE_FORMULA: {
                    if (DateUtil.isCellDateFormatted(cell)) {
                        cellValue = cell.getDateCellValue();
                    } else {
                        cellValue = cell.getNumericCellValue();
                    }
                    break;
                }
                case Cell.CELL_TYPE_BOOLEAN:
                    cellValue = cell.getBooleanCellValue();
                    break;
                default:
                    cellValue = cell.getStringCellValue();
            }
        }
        return cellValue;
    }

    private void setCellValue(Cell cell, Object value) {
        if (value == null) {
            cell.setCellValue("");
        } else if (value instanceof String) {
            cell.setCellValue((String) value);
        } else if (value instanceof Number) {
            cell.setCellValue(((Number) value).doubleValue());
        } else if (value instanceof RichTextString) {
            cell.setCellValue((RichTextString) value);
        } else if (value instanceof Boolean) {
            cell.setCellValue((Boolean) value);
        } else {
            cell.setCellValue(value.toString());
        }
    }

}

3.ExcelUtils类

package com.ydwl.business.campus.common.utils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.util.CollectionUtils;

/**
 * Excel 工具类(未优化版)
 * 请了解清除大致用法之后再用,不然有坑
 *
 * @author Kahle
 */
public class ExcelUtils {

    private static Log log = LogFactory.getLog(ExcelUtils.class);
    public static final Excel.Type DEFAULT_EXCEL_TYPE = Excel.Type.XLSX;

    public static Excel create() {
        return create(DEFAULT_EXCEL_TYPE);
    }

    public static Excel create(Excel.Type excelType) {
        switch (excelType) {
            case XLS:
                return new Excel(new HSSFWorkbook(), excelType);
            case XLSX:
                return new Excel(new XSSFWorkbook(), excelType);
            default:
                throw new RuntimeException("Excel type is error. ");
        }
    }

    public static Excel create(InputStream in) throws IOException {
        return create(DEFAULT_EXCEL_TYPE, in);
    }

    public static Excel create(String fileName, InputStream in) throws IOException {
        String suffix = fileName.substring(
                fileName.lastIndexOf('.')).toLowerCase();
        for (Excel.Type type : Excel.Type.values()) {
            if (type.getSuffix().equals(suffix)) {
                return create(type, in);
            }
        }
        return create(DEFAULT_EXCEL_TYPE, in);
    }

    public static Excel create(Excel.Type excelType, InputStream in) throws IOException {
        switch (excelType) {
            case XLS:
                return new Excel(new HSSFWorkbook(in), excelType);
            case XLSX:
                return new Excel(new XSSFWorkbook(in), excelType);
            default:
                throw new RuntimeException("Excel type is error. ");
        }
    }

    public static Excel createByFile(File file) throws IOException {
        if (file == null || !file.exists()) {
            throw new IllegalArgumentException("File is null or file not exist. ");
        }
        String filePath = file.toString();
        String suffix = filePath.substring(
                filePath.lastIndexOf('.')).toLowerCase();
        InputStream in = null;
        Excel result = null;
        try {
            in = new FileInputStream(file);
            for (Excel.Type type : Excel.Type.values()) {
                if (type.getSuffix().equals(suffix)) {
                    result = create(type, in);
                }
            }
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    log.error(e);
                }
            }
        }
        if (result != null) {
            return result;
        } else {
            throw new RuntimeException("Suffix in file is not excel suffix. ");
        }
    }

    public static <T> Excel createByBeans(List<T> beans) throws ReflectiveOperationException {
        return createByBeans(DEFAULT_EXCEL_TYPE, beans);
    }

    public static <T> Excel createByBeans(Excel.Type excelType, List<T> beans) throws ReflectiveOperationException {
        Excel result = create(excelType).createSheet();
        if (CollectionUtils.isEmpty(beans)) {
            throw new IllegalArgumentException("Beans is empty. ");
        }

        List<Method> usefulGetMethods = new ArrayList<>();
        List<Object> rowContent = new ArrayList<>();

        Class<?> clazz = beans.get(0).getClass();
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            String name = method.getName();
            if (method.isAccessible() && name.length() > 3 &&
                    name.indexOf("get") == 0) {
                usefulGetMethods.add(method);
                name = StringUtils.uncapitalize(name.substring(3));
                rowContent.add(name);
            }
        }
        result.writeRow(0, rowContent);

        for (int i = 0, len = beans.size(); i < len; i++) {
            rowContent.clear();
            for (Method method : usefulGetMethods) {
                rowContent.add(method.invoke(beans.get(i)));
            }
            result.writeRow(i + 1, rowContent);
        }

        return result;
    }

    public static <T> List<T> readToBeans(Excel excel, Class<T> clazz) throws ReflectiveOperationException {
        return readToBeans(excel, clazz, null);
    }

    public static <T> List<T> readToBeans(Excel excel, Class<T> clazz, Map<String, String> titlePropertyMap) throws ReflectiveOperationException {
        boolean hasTtlPpMap = false;
        if (MapUtils.isNotEmpty(titlePropertyMap)) {
            hasTtlPpMap = true;
        }

        List<T> result = new ArrayList<>();
        Integer lastRowNum = excel.getLastRowNum();
        if (lastRowNum <= 0) {
            throw new IllegalArgumentException("Excel not have row or not have data. ");
        }

        List<Method> usefulSetMethods = new ArrayList<>();
        List<?> rowContent;

        Method[] methods = clazz.getMethods();
        rowContent = excel.readRow(0);
        for (Object data : rowContent) {
            String name = data + "";
            if (hasTtlPpMap) {
                String tmp = titlePropertyMap.get(name);
                name = StringUtils.isNotBlank(tmp) ? tmp : name;
            }
            name = "set" + StringUtils.capitalize(name);
            int size = usefulSetMethods.size();
            for (Method method : methods) {
                if (StringUtils.equals(method.getName(), name)) {
                    usefulSetMethods.add(method);
                }
            }
            if (size + 1 != usefulSetMethods.size()) {
                throw new NoSuchMethodException("Method [" + name + "] not found in class [" + clazz.getName() + "].");
            }
        }

        for (int i = 1; i <= lastRowNum; i++) {
            rowContent = excel.readRow(i);
            if (CollectionUtils.isEmpty(rowContent)) {
                continue;
            }
            T bean = clazz.newInstance();
            for (int j = 0, size = rowContent.size(); j < size; j++) {
                Object val = rowContent.get(j);
                Class<?> valType = usefulSetMethods.get(j).getParameterTypes()[0];
                if (!val.getClass().equals(valType)) {
                    val = ConvertUtils.convert(val, valType);
                }
                usefulSetMethods.get(j).invoke(bean, val);
            }
            result.add(bean);
        }

        return result;
    }

    public static byte[] saveToBytes(Excel excel) throws IOException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        excel.write(out);
        return out.toByteArray();
    }

    public static void saveToFile(Excel excel, File file) throws IOException {
        OutputStream out = null;
        try {
            out = new FileOutputStream(file);
            excel.write(out);
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    log.error(e);
                }
            }
        }
    }
}

4.使用示例

private static final Map<String, String> excelMap = new HashMap<>();
//key值即excel的表头,value为自定义对象的属性
    static {
        excelMap.put("学号", "no");
        excelMap.put("姓名", "name");
        excelMap.put("性别", "sex");      
    }
Excel excel = ExcelUtils.create(file.getOriginalFilename(), file.getInputStream());
                excel.selectSheet(0);
List<YourObject> objectList = ExcelUtils.readToBeans(excel, YourObject.class, excelMap);

二、导出

1.maven导入

<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>2.1.6</version>
        </dependency>

2.工具类

package com.zhangmen.kids.wechat.utils;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import org.apache.poi.ss.usermodel.HorizontalAlignment;

import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;

public class ExcelUtil {
    /**
     * 导出
     *
     * @param response
     * @param data 导出的数据
     * @param fileName  文件名称
     * @param sheetName  sheet名称
     * @param clazz 导出数据对应的类
     * @throws Exception
     */
    public static void writeExcel(HttpServletResponse response, List<? extends Object> data, String fileName, String sheetName, Class clazz) throws Exception {
        //表头样式
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        //设置表头居中对齐
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        //内容样式
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        //设置内容靠左对齐
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
        EasyExcel.write(getOutputStream(fileName, response), clazz).excelType(ExcelTypeEnum.XLSX).sheet(sheetName).registerWriteHandler(horizontalCellStyleStrategy).doWrite(data);
    }

    private static OutputStream getOutputStream(String fileName, HttpServletResponse response) throws Exception {
        fileName = URLEncoder.encode(fileName, "UTF-8");
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
        return response.getOutputStream();
    }
}

3.定义导出的对象

/**
 * 资料领取详情导出excel
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@HeadRowHeight(value = 40)
public class StudentExcelProperty{

    @ExcelProperty(value = "姓名",index = 0)
    @ColumnWidth(value = 15)
    private String stuName;

    @ExcelProperty(value = "年龄",index = 1)
    @ColumnWidth(value = 20)
    private String age;

    @ExcelProperty(value = "性别",index = 2)
    @ColumnWidth(value = 20)
    private String sex;
}

4.使用示例

	String fileName = "学生导出";
	String sheetName = "学生导出";
	List<StudentExcelProperty> excelPropertyList = new ArrayList();
	try {
		ExcelUtil.writeExcel(response, excelPropertyList, fileName, sheetName, LearningResourceExcelProperty.class);
	} catch (Exception e) {
		e.printStackTrace();
	}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!