• ExcelUtil工具类-1


    package com.ltmst.util;
    
    import java.awt.image.BufferedImage;
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.net.URL;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    import java.util.Map;
    import javax.imageio.ImageIO;
    import javax.servlet.ServletOutputStream;
    import org.apache.poi.POIXMLException;
    import org.apache.poi.common.usermodel.Hyperlink;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    import org.apache.poi.ss.usermodel.Cell;
    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.xssf.usermodel.XSSFCell;
    import org.apache.poi.xssf.usermodel.XSSFCellStyle;
    import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
    import org.apache.poi.xssf.usermodel.XSSFCreationHelper;
    import org.apache.poi.xssf.usermodel.XSSFDrawing;
    import org.apache.poi.xssf.usermodel.XSSFFont;
    import org.apache.poi.xssf.usermodel.XSSFHyperlink;
    import org.apache.poi.xssf.usermodel.XSSFRow;
    import org.apache.poi.xssf.usermodel.XSSFSheet;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;
    import com.fivefu.base.pojo.ExcelCellData;
    import com.fivefu.base.pojo.ExcelDataType;
    
    /**
     * 封装了Excel的一些工具方法
     * @author Joy
     * @date 2020
     */
    public class ExcelUtil {
        /**单个sheet内最大行数*/
        public static final int MAX_SHEET_ROWS = 20000;
        /**单元格最小宽度*/
        public static final int MIN_COL_WIDTH = 12 * 256;
        /**单元格最大宽度*/
        public static final int MAX_COL_WIDTH = 255 * 256;
        
        /**
         * 计算列宽
         * @param colWidth 保存列宽设置的集合
         * @param colIndex 当前列的下标
         * @param content 当前列的内容(字符串形式)
         * @return 当前列的最佳列宽
         * @throws UnsupportedEncodingException
         * @author Joy
         * 
         */
        public static int calColWidth(List<Integer> colWidth, int colIndex, String content) throws UnsupportedEncodingException{
            int width = content.getBytes("UTF-8").length * 256 + 184;//根据当前内容计算单元格宽度
            if(width < ExcelUtil.MIN_COL_WIDTH){
                width = ExcelUtil.MIN_COL_WIDTH;
            }
            //每列的最大宽度不能超过255 * 256,超过这个值会报java.lang.IllegalArgumentException: the maximum column width in Excel is 255 characters
            if(width > ExcelUtil.MAX_COL_WIDTH){
                width = ExcelUtil.MAX_COL_WIDTH;
            }
            if(null == colWidth){
                colWidth = new ArrayList<Integer>();
            }
            if(colWidth.isEmpty() || colWidth.size() - 1 < colIndex){//如果列宽集合为空或者当前列不存在时就添加设置
                colWidth.add(width);
            }else{//否则读取设置
                //如果当前列的最佳列宽已经存在,就从列宽记录里面读取当前列的最佳列宽
                int bestWidth = colIndex > colWidth.size() - 1 ? width : (null != colWidth.get(colIndex) ? colWidth.get(colIndex).intValue() : width);
                if(bestWidth > width){//最佳宽度最合适,仍然取最佳宽度
                    colWidth.set(colIndex, bestWidth);
                }else{//否则说明当前数据的宽度超过了最佳宽度
                    colWidth.set(colIndex, width);
                }
            }
            return colIndex > colWidth.size() - 1 ? width : (null != colWidth.get(colIndex) ? colWidth.get(colIndex).intValue() : width);
        }
            
        /**
         * 写入标题到sheet中
         * @param workbook 工作表
         * @param sheet 要写入标题sheet
         * @param tableTitle 标题列表
         * @param titleCellStyle 标题样式,为空则没有任何样式应用
         * @param colWidth 列宽列表
         * @param isNoCellStyle 是否屏蔽单元格样式
         * @param isAutoCalCellWidth 是否自动计算列宽
         * @return 生成的行数
         * @throws Exception 抛出所有的异常
         * @author Joy
         * 
         */
        public static int writeTitleToSheet(XSSFWorkbook workbook, XSSFSheet sheet, List<String> tableTitle, XSSFCellStyle titleCellStyle, 
                List<Integer> colWidth, boolean isNoCellStyle, boolean isAutoCalCellWidth) throws Exception{
            int createRowNums = 0;//创建行的次数
            if(null != sheet && null != tableTitle && !tableTitle.isEmpty() && null != colWidth){
                XSSFRow titleRow = sheet.createRow(0);//创建标题行
                ++createRowNums;//每创建一行就累加一下行数
                //写入标题
                for(int i = 0; i < tableTitle.size(); ++i){
                    String content = null != tableTitle.get(i) ? tableTitle.get(i) : "";//取出标题内容
                    XSSFCell cell = titleRow.createCell(i);//创建单元格
                    cell.setCellValue(content);//设置单元格内容
                    if(!isNoCellStyle){//单元格计算样式
                        if(null != titleCellStyle){
                            cell.setCellStyle(titleCellStyle);//设置标题单元格样式
                        }else{
                            //设置字体
                            XSSFFont font = workbook.createFont();
                            font.setFontName("微软雅黑");//设置字体
                            
                            titleCellStyle = workbook.createCellStyle();//创建标题单元格样式
                            titleCellStyle.setBorderLeft(XSSFCellStyle.BORDER_THICK);//设置单元格左边框为厚厚的边框单元格样式
                            titleCellStyle.setBorderTop(XSSFCellStyle.BORDER_THICK);//设置单元格上边框为厚厚的边框单元格样式
                            titleCellStyle.setBorderRight(XSSFCellStyle.BORDER_THICK);//设置单元格右边框为厚厚的边框单元格样式
                            titleCellStyle.setBorderBottom(XSSFCellStyle.BORDER_THICK);//设置单元格下边框为厚厚的边框单元格样式
                            titleCellStyle.setAlignment(XSSFCellStyle.ALIGN_CENTER);//设置单元格对齐方式为水平居中
                            titleCellStyle.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);//设置单元格对齐方式为垂直居中
                            titleCellStyle.setFont(font);//将字体设置应用到标题中
                            
                            cell.setCellStyle(titleCellStyle);//设置标题单元格样式
                        }
                    }
                    if(isAutoCalCellWidth){//启用了自动个计算列宽
                        sheet.setColumnWidth(i, ExcelUtil.calColWidth(colWidth, i, content));//计算并设置列宽
                    }
                }
                sheet.createFreezePane(0, 1, 0, 1);//冻结首行
            }
            return createRowNums;
        }
        
        /**
         * 写入数据到sheet
         * @param workbook 工作表
         * @param sheet 要写入数据的sheet
         * @param sheetName sheet的名称
         * @param data 要写入的数据
         * @param cellStyle 数据单元格样式
         * @param colWidth 列宽列表
         * @param tableTitle 标题列表
         * @param titleCellStyle 标题样式
         * @param isNoCellStyle 是否屏蔽单元格样式
         * @param isAutoCalCellWidth 是否自动计算列宽
         * @throws Exception 抛出所有的异常
         * @author Joy
         * 
         */
        public static void writeDataToSheet(XSSFWorkbook workbook, XSSFSheet sheet, String sheetName, List<List<Object>> data, 
                XSSFCellStyle cellStyle, List<Integer> colWidth, List<String> tableTitle, XSSFCellStyle titleCellStyle,
                boolean isNoCellStyle, boolean isAutoCalCellWidth) throws Exception{
            if(null != workbook && null != sheet && null != data && !data.isEmpty()){
                if(null == colWidth){//如果列宽设置列表为空,就新建一个
                    colWidth = new ArrayList<Integer>();
                }
                int sheetNums = workbook.getNumberOfSheets();//获取excel内sheet的数量
                for(int i = 0; i < data.size(); ++i){
                    List<Object> colList = data.get(i);//获取一行所有列的数据
                    int sheetTotalRows = sheet.getPhysicalNumberOfRows();//更新每个sheet内的行数
                    //每当一个sheet内的行数达到20000行之后就创建一个新的sheet放数据
                    if(0 == sheetTotalRows % ExcelUtil.MAX_SHEET_ROWS){
                        sheet = workbook.createSheet((null != sheetName ? sheetName : "") + "第" + (sheetNums + 1) + "页");
                        ++sheetNums;//累加sheet数量
                        sheetTotalRows = 0;//计数器清零
                        //写入标题
                        sheetTotalRows += ExcelUtil.writeTitleToSheet(workbook, sheet, tableTitle, titleCellStyle, colWidth, isNoCellStyle, isAutoCalCellWidth);//写入标题到sheet中,并累加当前sheet中的行数
                    }
                    
                    XSSFRow row = sheet.createRow(sheetTotalRows);//创建新的一行
                    XSSFDrawing draw = null;
                    ++sheetTotalRows;//每创建一行就累加一下总行数
                    for(int j = 0; j < colList.size(); ++j){
                        Object obj = colList.get(j);//获取当前单元格数据
                        XSSFCell cell = row.createCell(j);//创建单元格
                        String content = "";//要写入的内容
                        if(obj instanceof ExcelCellData){
                            ExcelCellData cellData = (ExcelCellData)obj;//强转为Excel单元格数据信息对象
                            if(ExcelDataType.NUMBER == cellData.getDataType()){//要求按照数字格式写入数据
                                String value = cellData.getDataValue();//获取数据的字面值
                                cell.setCellValue(Double.parseDouble(value));//转为数字格式写入
                            }else if(ExcelDataType.DATE == cellData.getDataType()){//要求按照日期格式写入数据
                                Object value = cellData.getLinkData();//获取数据
                                if(value instanceof Date){//如果是日期类型
                                    cell.setCellValue((Date)value);//转换为日期类型写入数据
                                }else{//无法转换为日期类型
                                    cell.setCellValue(cellData.getDataValue());//直接获取当前数据的字面值数据写入,可能为空
                                }
                            }else if(ExcelDataType.IMG == cellData.getDataType()){//说明要写入的是图片
                                if(null == draw){//画笔为空时才实例化对象
                                    draw = sheet.createDrawingPatriarch();//往单元格中写入图片时使用
                                }
                                //String value = cellData.getDataValue();//获取图片地址
                                Object value = cellData.getLinkData();//获取图片资源
                                ExcelUtil.writeImgToOneCell(value, cell, draw, workbook);//向当前单元格中写入数据
                            }else if(ExcelDataType.LINK == cellData.getDataType()){//要写入的数据是外部链接类型
                                String text = cellData.getDataValue();//获取要显示的文本
                                Object link = cellData.getLinkData();//获取链接的资源
                                XSSFCreationHelper creationHelper = workbook.getCreationHelper();
                                String address = "";
                                String regExpEmail = "\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*";//邮箱正则表达式
                                String regExpURL = "[a-zA-z]+://[^\s]*";//URL正则表达式
                                XSSFHyperlink hyperLink = null;
                                if(link instanceof String){//链接内容可能是URL或者Email
                                    address = String.valueOf(link);//将内容转为文本
                                    if(address.matches(regExpURL)){//可能是一个URL
                                        hyperLink = (XSSFHyperlink)creationHelper.createHyperlink(Hyperlink.LINK_URL);//创建URL类型的链接
                                        hyperLink.setAddress(address);//设置链接地址
                                    }else if(address.matches(regExpEmail)){//可能是一个Email
                                        hyperLink = (XSSFHyperlink)creationHelper.createHyperlink(Hyperlink.LINK_EMAIL);//创建Email类型的链接
                                        hyperLink.setAddress(address);//设置链接地址
                                    }else{//如果两种都没有匹配上,就到外面去按照普通文本写入
                                        ;
                                    }
                                }else if(link instanceof File){//链接内容是外部文件
                                    File linkFile = (File)link;
                                    hyperLink = (XSSFHyperlink)creationHelper.createHyperlink(Hyperlink.LINK_FILE);//创建文件链接
                                    hyperLink.setAddress(linkFile.getAbsolutePath());//设置链接地址
                                }else{//本来还有一种链接类型是Hyperlink.LINK_DOCUMENT,暂未查到相关API,就直接当做普通文本写入不处理了
                                    ;
                                }
                                cell.setCellValue(text);//设置单元格显示的内容
                                if(null != hyperLink){
                                    cell.setHyperlink(hyperLink);
                                }
                            }else{//否则全部按照文字格式处理
                                content = String.valueOf(obj);
                                content = Sys.isNotNull(content) ? content : "";
                                
                                cell.setCellValue(content);//设置单元格数据
                            }
                        }else{//没有指明数据格式则全部按照文本格式写入数据
                            content = String.valueOf(obj);
                            content = Sys.isNotNull(content) ? content : "";
                            
                            cell.setCellValue(content);//设置单元格数据
                        }
                        
                        if(!isNoCellStyle){//单元格设置样式
                            if(null != cellStyle){
                                cell.setCellStyle(cellStyle);//设置单元格样式
                            }else{
                                //设置字体
                                XSSFFont font = workbook.createFont();
                                font.setFontName("微软雅黑");//设置字体
                                
                                cellStyle = workbook.createCellStyle();//创建数据区域表格样式
                                //设置单元格四周为浅边框线
                                cellStyle.setBorderLeft(XSSFCellStyle.BORDER_THIN);
                                cellStyle.setBorderTop(XSSFCellStyle.BORDER_THIN);
                                cellStyle.setBorderRight(XSSFCellStyle.BORDER_THIN);
                                cellStyle.setBorderBottom(XSSFCellStyle.BORDER_THIN);
                                cellStyle.setAlignment(XSSFCellStyle.ALIGN_JUSTIFY);//设置文本适应单元格内容的宽度
                                cellStyle.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);//设置文本垂直方向居中对齐
                                cellStyle.setFont(font);//将字体设置应用到数据区域中
                                
                                cell.setCellStyle(cellStyle);//设置单元格样式
                            }
                        }
                        if(isAutoCalCellWidth){//启用了自动计算列宽
                            sheet.setColumnWidth(j, ExcelUtil.calColWidth(colWidth, j, content));//设置列宽
                        }
                    }
                }
            }
        }
        
        /**
         * 追加形式写入数据到指定工作表中
         * @param workbook 要写入数据的工作表
         * @param tableTitle 表格标题
         * @param data 表格数据
         * @param sheetName 工作表名称
         * @param isNoCellStyle 是否屏蔽单元格样式
         * @param isAutoCalCellWidth 是否自动计算列宽
         * @throws Exception 抛出所有异常
         * @author Joy
         * 
         */
        public static void appendDataToExcel(XSSFWorkbook workbook, List<String> tableTitle, List<List<Object>> data, String sheetName,
                boolean isNoCellStyle, boolean isAutoCalCellWidth) throws Exception{
            if(null != workbook && null != tableTitle && !tableTitle.isEmpty() && null != data && !data.isEmpty()){
                int sheetNums = workbook.getNumberOfSheets();//获取工作表下sheet的数量
                
                XSSFFont font = null;//字体设置
                XSSFCellStyle titleCellStyle = null;//标题行单元格样式
                XSSFCellStyle cellStyle = null;//数据区域单元格样式
                List<Integer> colWidth = null;//用于保存列宽设置
                
                if(0 == sheetNums){//只有第一次开始写入的时候才实例化字体、单元格样式以及其他设置、计数器之类的
                    //设置字体
                    font = workbook.createFont();
                    font.setFontName("微软雅黑");//设置字体
                    
                    titleCellStyle = workbook.createCellStyle();//创建标题单元格样式
                    titleCellStyle.setBorderLeft(XSSFCellStyle.BORDER_THICK);//设置单元格左边框为厚厚的边框单元格样式
                    titleCellStyle.setBorderTop(XSSFCellStyle.BORDER_THICK);//设置单元格上边框为厚厚的边框单元格样式
                    titleCellStyle.setBorderRight(XSSFCellStyle.BORDER_THICK);//设置单元格右边框为厚厚的边框单元格样式
                    titleCellStyle.setBorderBottom(XSSFCellStyle.BORDER_THICK);//设置单元格下边框为厚厚的边框单元格样式
                    titleCellStyle.setAlignment(XSSFCellStyle.ALIGN_CENTER);//设置单元格对齐方式为水平居中
                    titleCellStyle.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);//设置单元格对齐方式为垂直居中
                    titleCellStyle.setFont(font);//将字体设置应用到标题中
                    
                    cellStyle = workbook.createCellStyle();//创建数据区域表格样式
                    //设置单元格四周为浅边框线
                    cellStyle.setBorderLeft(XSSFCellStyle.BORDER_THIN);
                    cellStyle.setBorderTop(XSSFCellStyle.BORDER_THIN);
                    cellStyle.setBorderRight(XSSFCellStyle.BORDER_THIN);
                    cellStyle.setBorderBottom(XSSFCellStyle.BORDER_THIN);
                    cellStyle.setAlignment(XSSFCellStyle.ALIGN_JUSTIFY);//设置文本适应单元格内容的宽度
                    cellStyle.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);//设置文本垂直方向居中对齐
                    cellStyle.setFont(font);//将字体设置应用到数据区域中
                    
                    if(null == colWidth){
                        colWidth = new ArrayList<Integer>();
                    }
                }
                
                XSSFSheet sheet = null;//工作表
                if(0 == sheetNums){//说明工作表中什么内容都没有,默认创建一张工作表,写入标题和数据
                    sheet = workbook.createSheet((null != sheetName ? sheetName : "") + "第" + (sheetNums + 1) + "页");//创建一个sheet
                    ExcelUtil.writeTitleToSheet(workbook, sheet, tableTitle, titleCellStyle, colWidth, isNoCellStyle, isAutoCalCellWidth);//写入标题到sheet中,并累加当前sheet中的行数
                    //写入数据
                    ExcelUtil.writeDataToSheet(workbook, sheet, sheetName, data, cellStyle, colWidth, tableTitle, titleCellStyle, isNoCellStyle, isAutoCalCellWidth);
                }else{//说明工作表中已经有数据了
                    /*
                     * 这个时候就需要注意了,这时就可以直接取出最后一个sheet(因为该方法是追加模式,每个sheet写满之后才创建新的sheet),
                     * 判断其行数是否超过每个sheet设定的最大行数,如果超过了就自动创建一个新的sheet并往里面写入数据
                     */
                    sheet = workbook.getSheetAt(sheetNums - 1);//取出最后一个sheet
                    //写入数据
                    ExcelUtil.writeDataToSheet(workbook, sheet, sheetName, data, cellStyle, colWidth, tableTitle, titleCellStyle, isNoCellStyle, isAutoCalCellWidth);
                }
            }
        }
        
        /**
         * 写入图片到一个单元格中
         * @param imgAddress 图片地址,可以是URL也可以是本地路径
         * @param rowIndex 写入单元格行下标
         * @param colIndex 写入单元格列下标
         * @param draw {@link XSSFDrawing}对象
         * @param workbook {@link XSSFWorkbook}对象,要写入图片的工作薄
         * @author Joy
         * 
         */
        public static void writeImgToOneCell(String imgAddress, int rowIndex, int colIndex, XSSFDrawing draw, XSSFWorkbook workbook){
            ByteArrayOutputStream byteArrayOut = null;
            try {
                byteArrayOut = new ByteArrayOutputStream();
                BufferedImage bufferImg = null;
                if(imgAddress.startsWith("http")){
                    bufferImg = ImageIO.read(new URL(imgAddress));
                }else{
                    bufferImg = ImageIO.read(new File(imgAddress));
                }
                String suffixName = imgAddress.substring(imgAddress.lastIndexOf(".") + 1);//获取文件后缀名
                ImageIO.write(bufferImg, suffixName, byteArrayOut);
                //表示图片写入一个单元格内且图片四周与单元格的边距为0
                XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, colIndex, (rowIndex + 1), (colIndex + 1), (rowIndex + 2));
                writeImgToCell(workbook, draw, anchor, byteArrayOut, suffixName);
            } catch (Exception e) {
                System.err.println("ExcelUtil.writeImgToOneCell方法Exception:" + e.getMessage());
                e.printStackTrace();
            } finally {
                if(null != byteArrayOut){
                    try {
                        byteArrayOut.flush();
                        byteArrayOut.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    
                }
            }
        }
        
        /**
         * 写入图片到一个单元格中
         * @param source 图片资源(目前只支持{@link URL}和{@link File})
         * @param cell {@link XSSFCell}对象,要写入图片的单元格
         * @param draw {@link XSSFDrawing}对象
         * @param workbook {@link XSSFWorkbook}对象,要写入图片的工作薄
         * @author Joy
         */
        public static void writeImgToOneCell(Object source, XSSFCell cell, XSSFDrawing draw, XSSFWorkbook workbook){
            ByteArrayOutputStream byteArrayOut = null;
            try {
                BufferedImage bufferImg = null;
                String suffixName = "jpg";//给个默认的图片格式,避免获取文件后缀名失败
                if(source instanceof URL){
                    byteArrayOut = new ByteArrayOutputStream();
                    URL url = (URL)source;
                    bufferImg = ImageIO.read(url);
                    String query = url.getPath();
                    suffixName = query.substring(query.lastIndexOf(".") + 1);//获取文件后缀名
                }else if(source instanceof File){
                    byteArrayOut = new ByteArrayOutputStream();
                    File file = (File)source;
                    bufferImg = ImageIO.read(file);
                    String addr = file.getAbsolutePath();
                    suffixName = addr.substring(addr.lastIndexOf(".") + 1);//获取文件后缀名
                }else{//如果没匹配上,就跳过当前单元格
                    return;
                }
                ImageIO.write(bufferImg, suffixName, byteArrayOut);
                //表示图片写入一个单元格内且图片四周与单元格的边距为0
                XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, cell.getColumnIndex(), cell.getRowIndex(), (cell.getColumnIndex() + 1), (cell.getRowIndex() + 1));
                writeImgToCell(workbook, draw, anchor, byteArrayOut, suffixName);
            } catch (Exception e) {
                System.err.println("ExcelUtil.writeImgToOneCell方法Exception:" + e.getMessage());
                e.printStackTrace();
            } finally {
                if(null != byteArrayOut){
                    try {
                        byteArrayOut.flush();
                        byteArrayOut.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    
                }
            }
        }
        
        /**
         * 写入图片到单元格
         * @param workbook 要写入图片的工作薄
         * @param draw {@link XSSFDrawing}对象
         * @param anchor {@link XSSFClientAnchor}对象
         * @param byteArrayOut {@link ByteArrayOutputStream}对象
         * @param suffixName 图片后缀名
         * @author Joy
         * 
         */
        private static void writeImgToCell(XSSFWorkbook workbook, XSSFDrawing draw, XSSFClientAnchor anchor, ByteArrayOutputStream byteArrayOut, String suffixName){
            try {
                //不同格式的图片采用不同的方法写入
                if("bmp".equalsIgnoreCase(suffixName)){
                    draw.createPicture(anchor, workbook.addPicture(byteArrayOut.toByteArray(), XSSFWorkbook.PICTURE_TYPE_BMP));
                }else if("eps".equalsIgnoreCase(suffixName)){
                    draw.createPicture(anchor, workbook.addPicture(byteArrayOut.toByteArray(), XSSFWorkbook.PICTURE_TYPE_EPS));
                }else if("gif".equalsIgnoreCase(suffixName)){
                    draw.createPicture(anchor, workbook.addPicture(byteArrayOut.toByteArray(), XSSFWorkbook.PICTURE_TYPE_GIF));
                }else if("tiff".equalsIgnoreCase(suffixName)){
                    draw.createPicture(anchor, workbook.addPicture(byteArrayOut.toByteArray(), XSSFWorkbook.PICTURE_TYPE_TIFF));
                }else if("jpg".equalsIgnoreCase(suffixName) || "jpeg".equalsIgnoreCase(suffixName)){
                    draw.createPicture(anchor, workbook.addPicture(byteArrayOut.toByteArray(), XSSFWorkbook.PICTURE_TYPE_JPEG));
                }else if("png".equalsIgnoreCase(suffixName)){
                    draw.createPicture(anchor, workbook.addPicture(byteArrayOut.toByteArray(), XSSFWorkbook.PICTURE_TYPE_PNG));
                }
            } catch (Exception e) {
                System.err.println("ExcelUtil.writeImgToCell方法Exception:" + e.getMessage());
                e.printStackTrace();
            }
        }
        
        /**
         * 读取单元格数据
         * @param cell 要读取数据的单元格
         * @return 有内容则返回{@link Object}类型的数据,否则返回<code>null</code>。
         * @author Joy
         * 
         */
        public static Object readCellData(Cell cell){
            Object cellContent = null;
            try {
                if(null != cell){
                    if(Cell.CELL_TYPE_NUMERIC == cell.getCellType()){//数字类型
                        cellContent = cell.getNumericCellValue();
                    }else if(Cell.CELL_TYPE_STRING == cell.getCellType()){//字符串类型
                        cellContent = cell.getStringCellValue();
                    }else if(Cell.CELL_TYPE_FORMULA == cell.getCellType()){//表达式类型
                        cellContent = cell.getCellFormula();
                    }else if(Cell.CELL_TYPE_BLANK == cell.getCellType()){//链接类型
                        cellContent = cell.getHyperlink();
                    }else if(Cell.CELL_TYPE_BOOLEAN == cell.getCellType()){//布尔值类型
                        cellContent = cell.getBooleanCellValue();
                    }else{//Cell.CELL_TYPE_ERROR类型,一个尚且未知的类型,姑且用String类型去读取(有可能会异常)
                        cellContent = cell.getStringCellValue();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return cellContent;
        }
        
        /**
         * 加载Excel文件
         * 先以2010方式加载excel文件,如果异常了再尝试以97/03方式加载excel文件。
         * @param excelFile 要加载的excel文件
         * @return 加载成功返回{@link Workbook}对象,否则返回<code>null</code>。
         * @author Joy
         * 
         */
        public static Workbook loadFile(File excelFile){
            Workbook workbook = null;
            try {
                workbook = new XSSFWorkbook(new FileInputStream(excelFile));//先用2010方式解析
                System.out.println("2010方式解析");
            } catch (POIXMLException e) {
                if(e.getMessage().indexOf("org.apache.poi.openxml4j.exceptions.InvalidFormatException") >= 0){//如果报格式异常就尝试用97/03格式解析
                    try {
                        workbook = new HSSFWorkbook(new FileInputStream(excelFile));//用97/03格式解析
                        System.out.println("97/03方式解析");
                    } catch (FileNotFoundException e1) {
                        System.err.println("Excel文件找不到");
                        e1.printStackTrace();
                    } catch (IOException e1) {
                        System.err.println("I/O异常");
                        e1.printStackTrace();
                    }
                }else{//未知异常
                    System.err.println("未知异常");
                    e.printStackTrace();
                }
            } catch (FileNotFoundException e) {
                System.err.println("Excel文件找不到");
                e.printStackTrace();
            } catch (IOException e) {
                System.err.println("I/O异常");
                e.printStackTrace();
            } catch (Exception e) {
                System.err.println("未知异常");
                e.printStackTrace();
            }
            return workbook;
        }
        
        /**
         * 读取Excel里的数据并写入{@link List}
         * @param excelFile 要读取数据的Excel
         * @return 读取到了数据返回{@link List}&lt;{@link List}&lt;{@link Object}&gt;&gt;集合,否则返回<code>null</code>。
         * @author Joy
         * 
         */
        public static List<List<Object>> readExcel(File excelFile){
            List<List<Object>> data = null;//用来保存解析出来的数据
            try {
                Workbook workbook = ExcelUtil.loadFile(excelFile);//加载Excel文件
                if(null != workbook){
                    data = new ArrayList<List<Object>>();
                    int sheets = workbook.getNumberOfSheets();//excel内不为空的sheet的总数量
                    //遍历所有的sheet,取出每个sheet中的数据
                    for(int sheetNum = 0; sheetNum < sheets; ++sheetNum){
                        Sheet sheet = workbook.getSheetAt(sheetNum);//获取当前sheet
                        int lastRowNum = sheet.getLastRowNum();//获取最后一行的下标
                        //遍历当前sheet中所有的行,取出每行的数据
                        for(int rowNum = 0; rowNum <= lastRowNum; ++rowNum){
                            Row row = sheet.getRow(rowNum);//获取当前行
                            int lastCellNum = row.getLastCellNum();//获取最后一列的下标
                            List<Object> rowData = new ArrayList<Object>(lastCellNum);//用来保存一行的数据
                            //遍历所有的列,取出当前行所有的数据
                            for(int colNum = 0; colNum < lastCellNum; ++colNum){
                                Cell cell = row.getCell(colNum);//获取当前单元格
                                Object cellValue = ExcelUtil.readCellData(cell);//读取单元格数据
                                rowData.add(cellValue);
                            }
                            data.add(rowData);
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return data;
        }
        
        
    }
  • 相关阅读:
    Excel两列查找重复值
    Docker容器的数据卷(data volume),数据卷容器,数据卷的备份和还原
    Ubuntu 搭建 GitLab 笔记 ***
    JIRA使用
    Android.mk文件LOCAL_MODULE_TAGS 说明
    Git Reset 三种模式
    Android常用的编译命令
    Android源码编译
    AOSP---"Android Open-Source Project"
    理解 Android Build 系统
  • 原文地址:https://www.cnblogs.com/weigy/p/13908777.html
Copyright © 2020-2023  润新知