poi的导入导出操作

/*
 * Copyright (c) 2017-2018. All rights reserved.
 *
 */

package com.bsj.sim.until.excelUtils;

import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ObjectUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Office Excel 导入导出操作
 *
 */
public class EXCELUtils {

    private final static Logger logger = LoggerFactory.getLogger(EXCELUtils.class);

    /**
     * 读取 2007版以上excel xls格式(默认是跳过有空单元格的行)
     *
     * @param targetFile 目标导入文件
     * @param clazz      需要写入的POJO类
     * @return 返回成功List和失败List的Map
     */
    public static Map<String, List<Object>> readXLSX(File targetFile, Class<?> clazz) {
        return readXLSX(targetFile, clazz, null, false, 1);
    }

    public static Map<String, List<Object>> readXLSX(File targetFile, Class<?> clazz, int startRowNum) {
        if (startRowNum < 2)
            throw new IllegalArgumentException("startRowNum must greater than 1.");
        return readXLSX(targetFile, clazz, null, false, startRowNum - 1);
    }

    /**
     * 读取 2007版以上excel xls格式(默认是跳过有空单元格的行)
     *
     * @param targetFile       目标导入文件
     * @param cloneableAdapter 需要写入的POJO类实例(支持内部类)
     * @return 返回成功List和失败List的Map
     */
    public static Map<String, List<Object>> readXLSX(File targetFile, CloneableAdapter cloneableAdapter) {
        return readXLSX(targetFile, cloneableAdapter, null);
    }

    /**
     * 读取 2007版以上excel xls格式
     *
     * @param targetFile   目标导入文件
     * @param clazz        需要写入的POJO类
     * @param nonEmptyCell 是否跳过有空单元格的行({@code true} 跳过,反之亦然)默认是{@code true}
     * @return 返回成功List和失败List的Map
     */
    public static Map<String, List<Object>> readXLSX(File targetFile, Class<?> clazz, Boolean nonEmptyCell, Boolean justFirstSheet, int startRowOffset) {
        if (nonEmptyCell == null)
            nonEmptyCell = true;
        if (justFirstSheet == null)
            justFirstSheet = false;
        Map resultMap = Maps.newHashMap();
        //导入成功的集合
        List<Object> rst0 = new ArrayList<>();
        //导入失败的集合
        List<Object> rst1 = new ArrayList<>();
        Object obj_;
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
        }
        try (XSSFWorkbook xssfWorkbook = new XSSFWorkbook(targetFile)) {
            //开始导入操作
            for (int numSheet = 0; numSheet < (justFirstSheet ? 1 : xssfWorkbook.getNumberOfSheets()); numSheet++) {
                XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(numSheet);
                //为空跳过
                if (xssfSheet == null) continue;
                int rowstart = xssfSheet.getFirstRowNum();
                int rowEnd = xssfSheet.getLastRowNum();
                // 从第二行开始读取
                rowstart = rowstart + startRowOffset;
                rowlab:
                for (int i = rowstart; i <= rowEnd; i++) {
//                    logger.debug("current rownum->" + i);
                    try {
                        obj_ = clazz.newInstance();
                        XSSFRow row = xssfSheet.getRow(i);
                        if (null == row && nonEmptyCell)
                            continue rowlab;
                        //添加空Cell过滤
                        //int cellStart = row.getFirstCellNum();
                        //int cellEnd = row.getLastCellNum();
                        int cellStart = 0;
                        int cellEnd = fields.length;
                        for (int k = cellStart; k < cellEnd; k++) {
                            XSSFCell cell = row.getCell(k);
                            if (null == cell && nonEmptyCell)
                                continue rowlab;
                            String cellVal = getValue(cell);
                            if (StringUtils.isEmpty(cellVal) && nonEmptyCell)
                                continue rowlab;
                            fields[k].set(obj_, cellVal);
                            //写到每行末时,添加到容器中(成功写入)
                            if (k == cellEnd - 1)
                                rst0.add(obj_);
//                            logger.debug("current rownum->" + i + " cell num-->" + k + "val-->" + cellVal);
                        }
                    } catch (Exception e) {
                        logger.error("本行导入失败-->" + e);
                        e.printStackTrace();
                        //本行写入失败则插入失败的集合
                        rst1.add(i + 1);
                    }
                }
            }
        } catch (IOException | InvalidFormatException | IllegalArgumentException e) {
            e.printStackTrace();
        }
        resultMap.put("success", rst0);
        resultMap.put("failure", rst1);
        return resultMap;
    }

    /**
     * 读取 2007版以上excel xls格式
     *
     * @param targetFile       目标导入文件
     * @param cloneableAdapter 需要写入的POJO类实例(支持内部类)
     * @param nonEmptyCell     是否跳过有空单元格的行({@code true} 跳过,反之亦然)默认是{@code true}
     * @return 返回成功List和失败List的Map
     */
    public static Map<String, List<Object>> readXLSX(File targetFile, CloneableAdapter cloneableAdapter, Boolean nonEmptyCell) {
        if (nonEmptyCell == null)
            nonEmptyCell = true;
        Map resultMap = Maps.newHashMap();
        //导入成功的集合
        List<Object> rst0 = new ArrayList<>();
        //导入失败的集合
        List<Object> rst1 = new ArrayList<>();
        Class<?> clazz = cloneableAdapter.getClass();
        Object obj_;
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
        }
        try (XSSFWorkbook xssfWorkbook = new XSSFWorkbook(targetFile)) {
            //开始导入操作
            for (int numSheet = 0; numSheet < xssfWorkbook.getNumberOfSheets(); numSheet++) {
                XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(numSheet);
                //为空跳过
                if (xssfSheet == null) continue;
                int rowstart = xssfSheet.getFirstRowNum();
                int rowEnd = xssfSheet.getLastRowNum();
                // 从第二行开始读取
                rowstart = rowstart + 1;
                rowlab:
                for (int i = rowstart; i <= rowEnd; i++) {
                    logger.debug("current rownum->" + i);
                    try {
                        obj_ = cloneableAdapter.clone();
                        XSSFRow row = xssfSheet.getRow(i);
                        if (null == row && nonEmptyCell)
                            continue rowlab;
                        //添加空Cell过滤
                        int cellStart = 0;
                        int cellEnd = fields.length;
                        for (int k = cellStart; k < cellEnd; k++) {
                            XSSFCell cell = row.getCell(k);
                            if (null == cell && nonEmptyCell)
                                continue rowlab;
                            String cellVal = getValue(cell);
                            if (StringUtils.isEmpty(cellVal) && nonEmptyCell)
                                continue rowlab;
                            fields[k].set(obj_, cellVal);
                            //写到每行末时,添加到容器中(成功写入)
                            if (k == cellEnd - 1)
                                rst0.add(obj_);
                            logger.debug("current rownum->" + i + " cell num-->" + k + "val-->" + cellVal);
                        }
                    } catch (Exception e) {
                        logger.error("Current Row Resolver Failure-->" + e);
                        e.printStackTrace();
                        //本行写入失败则插入失败的集合
                        rst1.add(i + 1);
                    }
                }
            }
        } catch (IOException | InvalidFormatException | IllegalArgumentException e) {
            e.printStackTrace();
        }
        resultMap.put("success", rst0);
        resultMap.put("failure", rst1);
        return resultMap;
    }

    private static String getValue(Cell cell) {
        if (ObjectUtils.isEmpty(cell))
            return null;
        if (cell.getCellType() == cell.CELL_TYPE_BOOLEAN) {
            return String.valueOf(cell.getBooleanCellValue());
        } else if (cell.getCellType() == cell.CELL_TYPE_NUMERIC) {
            String cellValue = "";
            if (HSSFDateUtil.isCellDateFormatted(cell)) {    //判断是日期类型
                SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
                Date dt = HSSFDateUtil.getJavaDate(cell.getNumericCellValue());//获取成DATE类型
                cellValue = dateformat.format(dt);
            } else {
                DecimalFormat df = new DecimalFormat("0");
                cellValue = df.format(cell.getNumericCellValue());
            }
            return cellValue;
        } else if (cell.getCellType() == cell.CELL_TYPE_FORMULA) {
            return cell.getCellFormula();
        } else {
            return String.valueOf(cell.getStringCellValue());
        }
    }

    /**
     * 读取 97-2003版excel xls格式
     *
     * @param targetFile
     * @param clazz
     * @return
     */
    public static Map<String, List<Object>> readXLS(File targetFile, Class<?> clazz) {
        Map resultMap = Maps.newHashMap();
        //导入成功的集合
        List<Object> rst0 = new ArrayList<>();
        //导入失败的集合
        List<Object> rst1 = new ArrayList<>();
        Object obj_;
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
        }
        try (HSSFWorkbook hssfWorkbook = new HSSFWorkbook(new POIFSFileSystem(new FileInputStream(targetFile)))) {
            HSSFSheet hssfSheet = hssfWorkbook.getSheetAt(0);
            int rowstart = hssfSheet.getFirstRowNum();
            int rowEnd = hssfSheet.getLastRowNum();
            for (int i = rowstart; i <= rowEnd; i++) {
                HSSFRow row = hssfSheet.getRow(i);
                if (null == row)
                    continue;
                try {
                    obj_ = clazz.newInstance();
                    int cellStart = row.getFirstCellNum();
                    int cellEnd = row.getLastCellNum();
                    for (int k = cellStart; k <= cellEnd; k++) {
                        HSSFCell cell = row.getCell(k);
                        if (null == cell)
                            continue;
                        fields[k].set(obj_, getValue(cell));
                        //switch (cell.getCellType()) {
                        //	case HSSFCell.CELL_TYPE_NUMERIC: // 数字
                        //		System.out.print(cell.getNumericCellValue() + "   ");
                        //		break;
                        //	case HSSFCell.CELL_TYPE_STRING: // 字符串
                        //		System.out.print(cell.getStringCellValue() + "   ");
                        //		break;
                        //	case HSSFCell.CELL_TYPE_BOOLEAN: // Boolean
                        //		System.out.println(cell.getBooleanCellValue() + "   ");
                        //		break;
                        //	case HSSFCell.CELL_TYPE_FORMULA: // 公式
                        //		System.out.print(cell.getCellFormula() + "   ");
                        //		break;
                        //	case HSSFCell.CELL_TYPE_BLANK: // 空值
                        //		System.out.println(" ");
                        //		break;
                        //	case HSSFCell.CELL_TYPE_ERROR: // 故障
                        //		System.out.println(" ");
                        //		break;
                        //	default:
                        //		System.out.print("未知类型   ");
                        //		break;
                        //}
                    }
                    //成功写入
                    rst0.add(obj_);
                } catch (Exception e) {
                    logger.error("current row-->" + targetFile.getPath() + "-->num-->" + (i + 1) + "-->" + e);
                    //e.printStackTrace();
                    //本行写入失败则插入失败的集合
                    rst1.add(i + 1);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        resultMap.put("success", rst0);
        resultMap.put("failure", rst1);
        return resultMap;
    }

    /*****************************************************************************/

    /**
     * 创建excel-xls文档,
     *
     * @param list        数据
     * @param keys        list中map的key数组集合
     * @param columnNames excel的列名
     * @return
     */
    public static Workbook createWorkBookXLS(List<Map<String, Object>> list, String[] keys, String columnNames[]) {
        // 创建excel工作簿
        Workbook wb = new HSSFWorkbook();
        // 创建第一个sheet(页),并命名
        Sheet sheet = wb.createSheet(list.get(0).get("sheetName").toString());
        // 手动设置列宽。第一个参数表示要为第几列设;,第二个参数表示列的宽度,n为列高的像素数。
        for (int i = 0; i < keys.length; i++) {
            sheet.setColumnWidth((short) i, (short) (35.7 * 150));
        }

        // 创建第一行
        Row row = sheet.createRow((short) 0);

        // 创建两种单元格格式
        CellStyle cs = wb.createCellStyle();
        CellStyle cs2 = wb.createCellStyle();

        // 创建两种字体
        Font f = wb.createFont();
        Font f2 = wb.createFont();

        // 创建第一种字体样式(用于列名)
        f.setFontHeightInPoints((short) 10);
        f.setColor(IndexedColors.BLACK.getIndex());
        f.setBoldweight(Font.BOLDWEIGHT_BOLD);

        // 创建第二种字体样式(用于值)
        f2.setFontHeightInPoints((short) 10);
        f2.setColor(IndexedColors.BLACK.getIndex());

        // Font f3=wb.createFont();
        // f3.setFontHeightInPoints((short) 10);
        // f3.setColor(IndexedColors.RED.getIndex());

        // 设置第一种单元格的样式(用于列名)
        cs.setFont(f);
        cs.setBorderLeft(CellStyle.BORDER_THIN);
        cs.setBorderRight(CellStyle.BORDER_THIN);
        cs.setBorderTop(CellStyle.BORDER_THIN);
        cs.setBorderBottom(CellStyle.BORDER_THIN);
        cs.setAlignment(CellStyle.ALIGN_CENTER);

        // 设置第二种单元格的样式(用于值)
        cs2.setFont(f2);
        cs2.setBorderLeft(CellStyle.BORDER_THIN);
        cs2.setBorderRight(CellStyle.BORDER_THIN);
        cs2.setBorderTop(CellStyle.BORDER_THIN);
        cs2.setBorderBottom(CellStyle.BORDER_THIN);
        cs2.setAlignment(CellStyle.ALIGN_CENTER);
        // 设置列名
        for (int i = 0; i < columnNames.length; i++) {
            Cell cell = row.createCell(i);
            cell.setCellValue(columnNames[i]);
            cell.setCellStyle(cs);
        }
        // 设置每行每列的值
        for (short i = 1; i < list.size(); i++) {
            // Row 行,Cell 方格 , Row 和 Cell 都是从0开始计数的
            // 创建一行,在页sheet上
            Row row1 = sheet.createRow((short) i);
            // 在row行上创建一个方格
            for (short j = 0; j < keys.length; j++) {
                Cell cell = row1.createCell(j);
                cell.setCellValue(list.get(i).get(keys[j]) == null ? " " : list.get(i).get(keys[j]).toString());
                cell.setCellStyle(cs2);
            }
        }
        return wb;
    }

    /**
     * 创建excel-xlsx文档,
     *
     * @param list        数据
     * @param keys        list中map的key数组集合
     * @param columnNames excel的列名
     * @return
     */
    public static Workbook createWorkBookXLSX(List<Map<String, Object>> list, String[] keys, String columnNames[]) {
        // 创建excel工作簿
        XSSFWorkbook wb = new XSSFWorkbook();
        // 创建第一个sheet(页),并命名
        XSSFSheet sheet = wb.createSheet(list.get(0).get("sheetName").toString());
        // 手动设置列宽。第一个参数表示要为第几列设;,第二个参数表示列的宽度,n为列高的像素数。
        for (int i = 0; i < keys.length; i++) {
            sheet.setColumnWidth((short) i, (short) (35.7 * 150));
        }

        //清除第一行
        list.remove(0);

        // 创建第一行
        XSSFRow row = sheet.createRow((short) 0);

        // 创建两种单元格格式
        XSSFCellStyle cs = wb.createCellStyle();
        XSSFCellStyle cs2 = wb.createCellStyle();

        // 创建两种字体
        XSSFFont f = wb.createFont();
        XSSFFont f2 = wb.createFont();

        // 创建第一种字体样式(用于列名)
        f.setFontHeightInPoints((short) 10);
        f.setColor(IndexedColors.BLACK.getIndex());
        f.setBoldweight(Font.BOLDWEIGHT_BOLD);

        // 创建第二种字体样式(用于值)
        f2.setFontHeightInPoints((short) 10);
        f2.setColor(IndexedColors.BLACK.getIndex());

        // Font f3=wb.createFont();
        // f3.setFontHeightInPoints((short) 10);
        // f3.setColor(IndexedColors.RED.getIndex());

        // 设置第一种单元格的样式(用于列名)
        cs.setFont(f);
        cs.setBorderLeft(CellStyle.BORDER_THIN);
        cs.setBorderRight(CellStyle.BORDER_THIN);
        cs.setBorderTop(CellStyle.BORDER_THIN);
        cs.setBorderBottom(CellStyle.BORDER_THIN);
        cs.setAlignment(CellStyle.ALIGN_CENTER);
//		cs.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//外边框颜色
//		cs.setFillPattern(CellStyle.SOLID_FOREGROUND);//背景色

        // 设置第二种单元格的样式(用于值)
        cs2.setFont(f2);
        cs2.setBorderLeft(CellStyle.BORDER_THIN);
        cs2.setBorderRight(CellStyle.BORDER_THIN);
        cs2.setBorderTop(CellStyle.BORDER_THIN);
        cs2.setBorderBottom(CellStyle.BORDER_THIN);
        cs2.setAlignment(CellStyle.ALIGN_CENTER);
        // 设置列名
        for (int i = 0; i < columnNames.length; i++) {
            XSSFCell cell = row.createCell(i);
            cell.setCellValue(columnNames[i]);
            cell.setCellStyle(cs);

        }
        // 设置每行每列的值
        for (short i = 0; i < list.size(); i++) {
            // Row 行,Cell 方格 , Row 和 Cell 都是从0开始计数的
            // 创建一行,在页sheet上
            XSSFRow row1 = sheet.createRow(i + 1);
            // 在row行上创建一个方格
            for (short j = 0; j < keys.length; j++) {
                XSSFCell cell = row1.createCell(j);
                cell.setCellValue(list.get(i).get(keys[j]) == null ? " " : list.get(i).get(keys[j]).toString());
                cell.setCellStyle(cs2);
            }
        }
        return wb;
    }

    public static String[][] dimenPut(Integer rows, Integer cols) {
        String[][] tmp = new String[rows][cols];
        for (int i = 0; i < tmp.length; i++) {
            for (int j = 0; j < tmp[i].length; j++) {
                tmp[i][j] = "老王" + i + "|老李" + j;
            }
        }
        return tmp;
    }

    public static List<Object> demoReflect(Object obj) {
        List<Object> rst0 = new ArrayList<Object>();
        Object obj_ = null;
        Method[] methods = obj.getClass().getDeclaredMethods();
        Method[] methods2 = new Method[methods.length];
        for (int i = 0, j = 0; i < methods.length; i++) {
            if (methods[i].getName().startsWith("set")) {
                // System.out.println(methods[i].getName());
                methods2[j] = methods[i];
                j++;
            }
        }
        String[][] tmp = dimenPut(3, 4);
        try {
            for (int i = 0; i < tmp.length; i++) {
                obj_ = obj.getClass().newInstance();
                for (int j = 0; j < tmp[i].length; j++) {
                    // System.out.println(tmp[i][j]);
                    methods2[j].invoke(obj_, tmp[i][j]);
                }
                rst0.add(obj_);
            }
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        return rst0;
    }

    public boolean writeXLS() {
        Boolean rst = false;
        HSSFWorkbook workbook = null;
        workbook = new HSSFWorkbook();
        // 获取参数个数作为excel列数
        int columeCount = 6;
        // 获取List size作为excel行数
        int rowCount = 20;
        HSSFSheet sheet = workbook.createSheet("sheet name");
        // 创建第一栏
        HSSFRow headRow = sheet.createRow(0);
        String[] titleArray = {"id", "name", "age", "email", "address", "phone"};
        for (int m = 0; m <= columeCount - 1; m++) {
            HSSFCell cell = headRow.createCell(m);
            cell.setCellType(HSSFCell.CELL_TYPE_STRING);
            sheet.setColumnWidth(m, 6000);
            HSSFCellStyle style = workbook.createCellStyle();
            HSSFFont font = workbook.createFont();
            font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
            short color = HSSFColor.RED.index;
            font.setColor(color);
            style.setFont(font);
            // 填写数据
            cell.setCellStyle(style);
            cell.setCellValue(titleArray[m]);
        }
        int index = 0;
        // 写入数据
        /*
         * for (RowEntity entity : pRowEntityList) { // logger.info("写入一行");
		 * HSSFRow row = sheet.createRow(index + 1); for (int n = 0; n <=
		 * columeCount - 1; n++) row.createCell(n);
		 * row.getCell(0).setCellValue(entity.getId());
		 * row.getCell(1).setCellValue(entity.getName());
		 * row.getCell(2).setCellValue(entity.getAge());
		 * row.getCell(3).setCellValue(entity.getEmail());
		 * row.getCell(4).setCellValue(entity.getAddress());
		 * row.getCell(5).setCellValue(entity.getPhone()); index++; }
		 */
        if (workbook != null) {
            try {
                workbook.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return rst;
    }

    public boolean writeXLSX() {
        Boolean rst = false;
        XSSFWorkbook workbook = new XSSFWorkbook();
        // 获取参数个数作为excel列数
        int columeCount = 6;
        // 获取List size作为excel行数
        int rowCount = 20;
        XSSFSheet sheet = workbook.createSheet("sheet name");
        // 创建第一栏
        XSSFRow headRow = sheet.createRow(0);
        String[] titleArray = {"id", "name", "age", "email", "address", "phone"};
        for (int m = 0; m <= columeCount - 1; m++) {
            XSSFCell cell = headRow.createCell(m);
            cell.setCellType(HSSFCell.CELL_TYPE_STRING);
            sheet.setColumnWidth(m, 6000);
            XSSFCellStyle style = workbook.createCellStyle();
            XSSFFont font = workbook.createFont();
            font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
            short color = HSSFColor.RED.index;
            font.setColor(color);
            style.setFont(font);
            // 填写数据
            cell.setCellStyle(style);
            cell.setCellValue(titleArray[m]);

        }
        int index = 0;
        // 写入数据
        // for (RowEntity entity : pRowEntityList) {
        // // logger.info("写入一行");
        // HSSFRow row = sheet.createRow(index + 1);
        // for (int n = 0; n <= columeCount - 1; n++)
        // row.createCell(n);
        // row.getCell(0).setCellValue(entity.getId());
        // row.getCell(1).setCellValue(entity.getName());
        // row.getCell(2).setCellValue(entity.getAge());
        // row.getCell(3).setCellValue(entity.getEmail());
        // row.getCell(4).setCellValue(entity.getAddress());
        // row.getCell(5).setCellValue(entity.getPhone());
        // index++;
        // }
        if (workbook != null) {
            try {
                workbook.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return rst;
    }

}

发布了33 篇原创文章 · 获赞 0 · 访问量 1461

猜你喜欢

转载自blog.csdn.net/m0_46086429/article/details/104281369