zoukankan      html  css  js  c++  java
  • java读取excel的工具类-POI解析excel

    分享一个操作excel的工具类,这个工具分3个部分,

    ExcelUtil.java   //工具类

    ExcelSheetPO.java  //实体对象

    ExcelVersion.java //版本枚举

     

    可以把excel数据读取到内存中,转换为 List<List<Object>>,也可以根据List<List<Object>>转化成excel文件

     

    依赖的jar包是poi,有用到spring框架的集合工具类,不能依赖的可以动手改改

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

     

    ExcelUtil.java

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.text.DecimalFormat;
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.LinkedList;
    import java.util.List;
    
    import org.apache.commons.collections.CollectionUtils;
    import org.apache.poi.hssf.usermodel.HSSFCellStyle;
    import org.apache.poi.hssf.usermodel.HSSFDateUtil;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    import org.apache.poi.ss.usermodel.Cell;
    import org.apache.poi.ss.usermodel.CellStyle;
    import org.apache.poi.ss.usermodel.CellValue;
    import org.apache.poi.ss.usermodel.Font;
    import org.apache.poi.ss.usermodel.FormulaEvaluator;
    import org.apache.poi.ss.usermodel.Row;
    import org.apache.poi.ss.usermodel.Sheet;
    import org.apache.poi.ss.usermodel.Workbook;
    import org.apache.poi.ss.util.CellRangeAddress;
    import org.apache.poi.ss.util.WorkbookUtil;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;
    
    import com.zkingsoft.common.tools.FileUtil;
    
    /**
     * excel工具类 提供读取和写入excel的功能
     * 
     * @author JIANGYOUYAO
     * @email 935090232@qq.com
     * @date 2017年12月20日
     */
    public class ExcelUtil {
    
        /**
         * 标题样式
         */
        private final static String STYLE_HEADER = "header";
        /**
         * 表头样式
         */
        private final static String STYLE_TITLE = "title";
        /**
         * 数据样式
         */
        private final static String STYLE_DATA = "data";
    
        /**
         * 存储样式
         */
        private static final HashMap<String, CellStyle> cellStyleMap = new HashMap<>();
    
        /**
         * 读取excel文件里面的内容 支持日期,数字,字符,函数公式,布尔类型
         * 
         * @author JIANGYOUYAO
         * @email 935090232@qq.com
         * @date 2017年12月20日
         * @param file
         * @param rowCount
         * @param columnCount
         * @return
         * @throws FileNotFoundException
         * @throws IOException
         */
        public static List<ExcelSheetPO> readExcel(File file, Integer rowCount, Integer columnCount)
                throws FileNotFoundException, IOException {
    
            // 根据后缀名称判断excel的版本
            String extName = FileUtil.getFileExtName(file);
            Workbook wb = null;
            if (ExcelVersion.V2003.getSuffix().equals(extName)) {
                wb = new HSSFWorkbook(new FileInputStream(file));
    
            } else if (ExcelVersion.V2007.getSuffix().equals(extName)) {
                wb = new XSSFWorkbook(new FileInputStream(file));
    
            } else {
                // 无效后缀名称,这里之能保证excel的后缀名称,不能保证文件类型正确,不过没关系,在创建Workbook的时候会校验文件格式
                throw new IllegalArgumentException("Invalid excel version");
            }
            // 开始读取数据
            List<ExcelSheetPO> sheetPOs = new ArrayList<>();
            // 解析sheet
            for (int i = 0; i < wb.getNumberOfSheets(); i++) {
                Sheet sheet = wb.getSheetAt(i);
                List<List<Object>> dataList = new ArrayList<>();
                ExcelSheetPO sheetPO = new ExcelSheetPO();
                sheetPO.setSheetName(sheet.getSheetName());
                sheetPO.setDataList(dataList);
                int readRowCount = 0;
                if (rowCount == null || rowCount > sheet.getPhysicalNumberOfRows()) {
                    readRowCount = sheet.getPhysicalNumberOfRows();
                } else {
                    readRowCount = rowCount;
                }
                // 解析sheet 的行
                for (int j = sheet.getFirstRowNum(); j < readRowCount; j++) {
                    Row row = sheet.getRow(j);
                    if (row == null) {
                        continue;
                    }
                    if (row.getFirstCellNum() < 0) {
                        continue;
                    }
                    int readColumnCount = 0;
                    if (columnCount == null || columnCount > row.getLastCellNum()) {
                        readColumnCount = (int) row.getLastCellNum();
                    } else {
                        readColumnCount = columnCount;
                    }
                    List<Object> rowValue = new LinkedList<Object>();
                    // 解析sheet 的列
                    for (int k = 0; k < readColumnCount; k++) {
                        Cell cell = row.getCell(k);
                        rowValue.add(getCellValue(wb, cell));
                    }
                    dataList.add(rowValue);
                }
                sheetPOs.add(sheetPO);
            }
            return sheetPOs;
        }
    
        private static Object getCellValue(Workbook wb, Cell cell) {
            Object columnValue = null;
            if (cell != null) {
                DecimalFormat df = new DecimalFormat("0");// 格式化 number
                // String
                // 字符
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 格式化日期字符串
                DecimalFormat nf = new DecimalFormat("0.00");// 格式化数字
                switch (cell.getCellType()) {
                case Cell.CELL_TYPE_STRING:
                    columnValue = cell.getStringCellValue();
                    break;
                case Cell.CELL_TYPE_NUMERIC:
                    if ("@".equals(cell.getCellStyle().getDataFormatString())) {
                        columnValue = df.format(cell.getNumericCellValue());
                    } else if ("General".equals(cell.getCellStyle().getDataFormatString())) {
                        columnValue = nf.format(cell.getNumericCellValue());
                    } else {
                        columnValue = sdf.format(HSSFDateUtil.getJavaDate(cell.getNumericCellValue()));
                    }
                    break;
                case Cell.CELL_TYPE_BOOLEAN:
                    columnValue = cell.getBooleanCellValue();
                    break;
                case Cell.CELL_TYPE_BLANK:
                    columnValue = "";
                    break;
                case Cell.CELL_TYPE_FORMULA:
                    // 格式单元格
                    FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
                    evaluator.evaluateFormulaCell(cell);
                    CellValue cellValue = evaluator.evaluate(cell);
                    columnValue = cellValue.getNumberValue();
                    break;
                default:
                    columnValue = cell.toString();
                }
            }
            return columnValue;
        }
    
        /**
         * 在硬盘上写入excel文件
         * 
         * @author JIANGYOUYAO
         * @email 935090232@qq.com
         * @date 2017年12月20日
         * @param version
         * @param excelSheets
         * @param filePath
         * @throws IOException
         */
        public static void createWorkbookAtDisk(ExcelVersion version, List<ExcelSheetPO> excelSheets, String filePath)
                throws IOException {
            FileOutputStream fileOut = new FileOutputStream(filePath);
            createWorkbookAtOutStream(version, excelSheets, fileOut, true);
        }
    
        /**
         * 把excel表格写入输出流中,输出流会被关闭
         * 
         * @author JIANGYOUYAO
         * @email 935090232@qq.com
         * @date 2017年12月20日
         * @param version
         * @param excelSheets
         * @param outStream
         * @param closeStream
         *            是否关闭输出流
         * @throws IOException
         */
        public static void createWorkbookAtOutStream(ExcelVersion version, List<ExcelSheetPO> excelSheets,
                OutputStream outStream, boolean closeStream) throws IOException {
            if (CollectionUtils.isNotEmpty(excelSheets)) {
                Workbook wb = createWorkBook(version, excelSheets);
                wb.write(outStream);
                if (closeStream) {
                    outStream.close();
                }
            }
        }
    
        private static Workbook createWorkBook(ExcelVersion version, List<ExcelSheetPO> excelSheets) {
            Workbook wb = createWorkbook(version);
            for (int i = 0; i < excelSheets.size(); i++) {
                ExcelSheetPO excelSheetPO = excelSheets.get(i);
                if (excelSheetPO.getSheetName() == null) {
                    excelSheetPO.setSheetName("sheet" + i);
                }
                // 过滤特殊字符
                Sheet tempSheet = wb.createSheet(WorkbookUtil.createSafeSheetName(excelSheetPO.getSheetName()));
                buildSheetData(wb, tempSheet, excelSheetPO, version);
            }
            return wb;
        }
    
        private static void buildSheetData(Workbook wb, Sheet sheet, ExcelSheetPO excelSheetPO, ExcelVersion version) {
            sheet.setDefaultRowHeight((short) 400);
            sheet.setDefaultColumnWidth((short) 10);
            createTitle(sheet, excelSheetPO, wb, version);
            createHeader(sheet, excelSheetPO, wb, version);
            createBody(sheet, excelSheetPO, wb, version);
        }
    
        private static void createBody(Sheet sheet, ExcelSheetPO excelSheetPO, Workbook wb, ExcelVersion version) {
            List<List<Object>> dataList = excelSheetPO.getDataList();
            for (int i = 0; i < dataList.size() && i < version.getMaxRow(); i++) {
                List<Object> values = dataList.get(i);
                Row row = sheet.createRow(2 + i);
                for (int j = 0; j < values.size() && j < version.getMaxColumn(); j++) {
                    Cell cell = row.createCell(j);
                    cell.setCellStyle(getStyle(STYLE_DATA, wb));
                    cell.setCellValue(values.get(j).toString());
                }
            }
    
        }
    
        private static void createHeader(Sheet sheet, ExcelSheetPO excelSheetPO, Workbook wb, ExcelVersion version) {
            String[] headers = excelSheetPO.getHeaders();
            Row row = sheet.createRow(1);
            for (int i = 0; i < headers.length && i < version.getMaxColumn(); i++) {
                Cell cellHeader = row.createCell(i);
                cellHeader.setCellStyle(getStyle(STYLE_HEADER, wb));
                cellHeader.setCellValue(headers[i]);
            }
    
        }
    
        private static void createTitle(Sheet sheet, ExcelSheetPO excelSheetPO, Workbook wb, ExcelVersion version) {
            Row titleRow = sheet.createRow(0);
            Cell titleCel = titleRow.createCell(0);
            titleCel.setCellValue(excelSheetPO.getTitle());
            titleCel.setCellStyle(getStyle(STYLE_TITLE, wb));
            // 限制最大列数
            int column = excelSheetPO.getDataList().size() > version.getMaxColumn() ? version.getMaxColumn()
                    : excelSheetPO.getDataList().size();
            sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, column - 1));
        }
    
        private static CellStyle getStyle(String type, Workbook wb) {
    
            if (cellStyleMap.containsKey(type)) {
                return cellStyleMap.get(type);
            }
            // 生成一个样式
            CellStyle style = wb.createCellStyle();
            style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
            style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
            style.setBorderRight(HSSFCellStyle.BORDER_THIN);
            style.setBorderTop(HSSFCellStyle.BORDER_THIN);
            style.setWrapText(true);
    
            if (STYLE_HEADER == type) {
                style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
                Font font = wb.createFont();
                font.setFontHeightInPoints((short) 16);
                font.setBoldweight(Font.BOLDWEIGHT_BOLD);
                style.setFont(font);
            } else if (STYLE_TITLE == type) {
                style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
                Font font = wb.createFont();
                font.setFontHeightInPoints((short) 18);
                font.setBoldweight(Font.BOLDWEIGHT_BOLD);
                style.setFont(font);
            } else if (STYLE_DATA == type) {
                style.setAlignment(HSSFCellStyle.ALIGN_LEFT);
                Font font = wb.createFont();
                font.setFontHeightInPoints((short) 12);
                style.setFont(font);
            }
            cellStyleMap.put(type, style);
            return style;
        }
    
        private static Workbook createWorkbook(ExcelVersion version) {
            switch (version) {
            case V2003:
                return new HSSFWorkbook();
            case V2007:
                return new XSSFWorkbook();
            }
            return null;
        }
    }

    ExcelSheetPO.java  

     

    package com.zkingsoft.common.tools.excel;
    
    import java.util.List;
    
    /**
     * 定义表格的数据对象
     * @author JIANGYOUYAO
     * @email 935090232@qq.com
     * @date 2017年12月20日
     */
    public class ExcelSheetPO {
    
        /**
         * sheet的名称
         */
        private String sheetName;
    
     
        /**
         * 表格标题
         */
        private String title;
    
        /**
         * 头部标题集合
         */
        private String[] headers;
    
        /**
         * 数据集合
         */
        private List<List<Object>> dataList;
    
        public String getTitle() {
            return title;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    
        public String[] getHeaders() {
            return headers;
        }
    
        public void setHeaders(String[] headers) {
            this.headers = headers;
        }
    
        public List<List<Object>> getDataList() {
            return dataList;
        }
    
        public void setDataList(List<List<Object>> dataList) {
            this.dataList = dataList;
        }
    
        public String getSheetName() {
            return sheetName;
        }
    
        public void setSheetName(String sheetName) {
            this.sheetName = sheetName;
        }
        
        
    
    }

    ExcelVersion.java

     

    package com.zkingsoft.common.tools.excel;
    
    /**
     * excel版本枚举
     * 
     * @author JIANGYOUYAO
     * @email 935090232@qq.com
     * @date 2017年12月20日
     */
    public enum ExcelVersion {
    
        /**
         * 虽然V2007版本支持最大支持1048575 * 16383 , 
         * V2003版支持65535*255
         * 但是在实际应用中如果使用如此庞大的对象集合会导致内存溢出,
         * 因此这里限制最大为10000*100,如果还要加大建议先通过单元测试进行性能测试。
         * 1000*100 全部导出预计时间为27s左右
         */
        V2003(".xls", 10000, 100), V2007(".xlsx", 100, 100);
    
        private String suffix;
    
        private int maxRow;
    
        private int maxColumn;
    
        ExcelVersion(String suffix, int maxRow, int maxColumn) {
            this.suffix = suffix;
            this.maxRow = maxRow;
            this.maxColumn = maxColumn;
        }
    
        public String getSuffix() {
            return this.suffix;
        }
    
        public int getMaxRow() {
            return maxRow;
        }
    
        public void setMaxRow(int maxRow) {
            this.maxRow = maxRow;
        }
    
        public int getMaxColumn() {
            return maxColumn;
        }
    
        public void setMaxColumn(int maxColumn) {
            this.maxColumn = maxColumn;
        }
    
        public void setSuffix(String suffix) {
            this.suffix = suffix;
        }
    
    }

    如果有改进的地方欢迎留言

  • 相关阅读:
    Git工具简介
    Windows10搭建开发环境----Maven工具安装
    SpringBoot----01.SpringBoot基本配置
    创建一个SpringBoot项目
    软件工程----02. 需求分析
    软件工程----01. 软件工程简介
    JavaSE----11.Java 内部类
    JavaSE----10.Java 面向对象
    JavaSE----09.Java 数组
    前端面试总结
  • 原文地址:https://www.cnblogs.com/jyyjava/p/8074322.html
Copyright © 2011-2022 走看看