若依 ruoyi poi Excel归并行的导入

打印 上一主题 下一主题

主题 561|帖子 561|积分 1683

本文仅针对文字相干的归并做了处理 ,图片归并及保存需要另做处理!!

目的:Excel归并行内容的导入

结果:



1. ExcelUtil.java 类,新增方法:判断是否是归并行
  1.     /**
  2.      * 新增 合并行相关代码:判断是否是合并行
  3.      *
  4.      * @param sheet
  5.      * @param row
  6.      * @param column
  7.      * @return
  8.      */
  9.     private boolean isMergedRow(Sheet sheet, int row, int column) {
  10.         int sheetMergeCount = sheet.getNumMergedRegions();//当前表格(sheet)中,所有合单元格总数
  11.         //遍历所有合并单元格
  12.         for (int i = 0; i < sheetMergeCount; i++) {
  13.             CellRangeAddress cellAddresses = sheet.getMergedRegion(i);//当前合并单元格对象
  14.             int firstColumn = cellAddresses.getFirstColumn();//当前合并单元格的首列
  15.             int lastColumn = cellAddresses.getLastColumn();//当前合并单元格的末列
  16.             int firstRow = cellAddresses.getFirstRow();//当前合并单元格的首行
  17.             int lastRow = cellAddresses.getLastRow();//当前合并单元格的末行
  18.             //指定的行 包含在合并单元格中
  19.             if (row >= firstRow && row <= lastRow) {
  20.                 //指定的列 包含在合并单元格中
  21.                 if (column >= firstColumn && column <= lastColumn) {
  22.                     return true;
  23.                 }
  24.             }
  25.         }
  26.         return false;
  27.     }
复制代码

2. ExcelUtil.java 类,新增方法:获取归并行单位格数据
思绪:
POI对于Excel的处理:归并行中 只有首列能获取到值  非首列的其他列数据默认是空。由于是归并行,则可以以为  归并行内所有列的数据  都与归并行的首列数据雷同。
所以,以下代码中,判断该列如果包含在归并行内,则该列值默认赋值为 所在归并行的首列值。
 图1 Excel中的2/3/4行内的归并行内容雷同:

 POI对Excel处理时,默认获取到的值大概如图2:下面代码则在图2逻辑上 对3/4行的空内容做赋值操纵


  1.     /**
  2.      * 新增 合并行相关代码:获取合并行的数据
  3.      *
  4.      * @param sheet
  5.      * @param row
  6.      * @param column
  7.      * @return
  8.      */
  9.     private String getMergedRegionValue(Sheet sheet, int row, int column) {
  10.         // 获得该sheet所有合并单元格数量
  11.         int sheetMergeCount = sheet.getNumMergedRegions();
  12.         for (int i = 0; i < sheetMergeCount; i++) {
  13.             // 获得合并区域
  14.             CellRangeAddress cellAddresses = sheet.getMergedRegion(i);
  15.             int firstColumn = cellAddresses.getFirstColumn();
  16.             int lastColumn = cellAddresses.getLastColumn();
  17.             int firstRow = cellAddresses.getFirstRow();
  18.             int lastRow = cellAddresses.getLastRow();
  19.             /*判断传入的单元格的行号列号是否在合并单元格的范围内,
  20.             如果在合并单元格的范围内,择返回合并区域的首单元格格值
  21.              */
  22.             if (row >= firstRow && row <= lastRow) {
  23.                 if (column >= firstColumn && column <= lastColumn) {
  24.                     Row firRow = sheet.getRow(firstRow);
  25.                     /* 合并行使用的获取单元格内容方法
  26.                     Cell firCell = firRow.getCell(firstColumn);
  27.                     return getCellValue(firCell);
  28.                      */
  29.                     return getCellValue(firRow, firstColumn).toString();//改为使用 若依自带获取单元格内容方法
  30.                 }
  31.             }
  32.         }
  33.         // 如果该单元格行号列号不在任何一个合并区域,则返回null
  34.         return null;
  35.     }
复制代码

3. ExcelUtil.java的importExcel()方法中 遍历行内所有单位格内容下,新增: 归并行的判断 和 其内单位格内容获取

  1. // ============== 新增 合并行相关代码块 ================
  2. // 判断是否合并行  isMergedRow(sheet, rowNum, column):是合并行,则获取合并行数据 重新赋值给当前列
  3. if (isMergedRow(sheet, i, entry.getKey())) val = getMergedRegionValue(sheet, i, entry.getKey());
  4. // ============== 新增 合并行相关代码块 ================
复制代码
importExcel()方法完整代码
  1.     /**
  2.      * 对excel表单指定表格索引名转换成list
  3.      *
  4.      * @param sheetName 表格索引名
  5.      * @param titleNum 标题占用行数
  6.      * @param is 输入流
  7.      * @return 转换后集合
  8.      */
  9.     public List<T> importExcel(String sheetName, InputStream is, int titleNum) throws Exception
  10.     {
  11.         this.type = Type.IMPORT;
  12.         this.wb = WorkbookFactory.create(is);
  13.         List<T> list = new ArrayList<T>();
  14.         // 如果指定sheet名,则取指定sheet中的内容 否则默认指向第1个sheet
  15.         Sheet sheet = StringUtils.isNotEmpty(sheetName) ? wb.getSheet(sheetName) : wb.getSheetAt(0);
  16.         if (sheet == null)
  17.         {
  18.             throw new IOException("文件sheet不存在");
  19.         }
  20.         boolean isXSSFWorkbook = !(wb instanceof HSSFWorkbook);
  21.         //获取文档指定sheet中所有图片:图片位置、文件流
  22.         Map<String, PictureData> pictures;
  23.         if (isXSSFWorkbook)
  24.         {
  25.             pictures = getSheetPictures07((XSSFSheet) sheet, (XSSFWorkbook) wb);
  26.         }
  27.         else
  28.         {
  29.             pictures = getSheetPictures03((HSSFSheet) sheet, (HSSFWorkbook) wb);
  30.         }
  31.         // 获取最后一个非空行的行下标,比如总行数为n,则返回的为n-1
  32.         int rows = sheet.getLastRowNum();
  33.         if (rows > 0)
  34.         {
  35.             // 定义一个map用于存放excel列的序号和field.
  36.             Map<String, Integer> cellMap = new HashMap<String, Integer>();
  37.             // 获取表头
  38.             Row heard = sheet.getRow(titleNum);
  39.             for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++)
  40.             {
  41.                 Cell cell = heard.getCell(i);
  42.                 if (StringUtils.isNotNull(cell))
  43.                 {
  44.                     String value = this.getCellValue(heard, i).toString();
  45.                     cellMap.put(value, i);
  46.                 }
  47.                 else
  48.                 {
  49.                     cellMap.put(null, i);
  50.                 }
  51.             }
  52.             // 有数据时才处理 得到类的所有field.
  53.             List<Object[]> fields = this.getFields();
  54.             Map<Integer, Object[]> fieldsMap = new HashMap<Integer, Object[]>();
  55.             for (Object[] objects : fields)
  56.             {
  57.                 Excel attr = (Excel) objects[1];
  58.                 Integer column = cellMap.get(attr.name());
  59.                 if (column != null)
  60.                 {
  61.                     fieldsMap.put(column, objects);
  62.                 }
  63.             }
  64.             //遍历每一行
  65.             for (int i = titleNum + 1; i <= rows; i++)
  66.             {
  67.                 // 从第2行开始取数据,默认第一行是表头.
  68.                 Row row = sheet.getRow(i);
  69.                 // 判断当前行是否是空行
  70.                 if (isRowEmpty(row))
  71.                 {
  72.                     continue;
  73.                 }
  74.                 T entity = null;
  75.                 //遍历当前行所有列 逐列字段值获取并赋值给entity对象的各属性
  76.                 for (Map.Entry<Integer, Object[]> entry : fieldsMap.entrySet())
  77.                 {
  78.                     Object val = this.getCellValue(row, entry.getKey());//获取当前列 默认值
  79.                     // ============== 新增 合并行相关代码块 ================
  80.                     // 判断是否合并行  isMergedRow(sheet, rowNum, column):是合并行,则获取合并行首列数据 重新赋值给当前列
  81.                     if (isMergedRow(sheet, i, entry.getKey())) val = getMergedRegionValue(sheet, i, entry.getKey());
  82.                     // ============== 新增 合并行相关代码块 ================
  83.                     // 如果不存在实例则新建.
  84.                     entity = (entity == null ? clazz.newInstance() : entity);
  85.                     // 从map中得到对应列的field.
  86.                     Field field = (Field) entry.getValue()[0];
  87.                     Excel attr = (Excel) entry.getValue()[1];
  88.                     // 取得类型,并根据对象类型设置值.
  89.                     Class<?> fieldType = field.getType();
  90.                     if (String.class == fieldType)
  91.                     {
  92.                         String s = Convert.toStr(val);
  93.                         if (StringUtils.endsWith(s, ".0"))
  94.                         {
  95.                             val = StringUtils.substringBefore(s, ".0");
  96.                         }
  97.                         else
  98.                         {
  99.                             String dateFormat = field.getAnnotation(Excel.class).dateFormat();
  100.                             if (StringUtils.isNotEmpty(dateFormat))
  101.                             {
  102.                                 val = parseDateToStr(dateFormat, val);
  103.                             }
  104.                             else
  105.                             {
  106.                                 val = Convert.toStr(val);
  107.                             }
  108.                         }
  109.                     }
  110.                     else if ((Integer.TYPE == fieldType || Integer.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val)))
  111.                     {
  112.                         val = Convert.toInt(val);
  113.                     }
  114.                     else if ((Long.TYPE == fieldType || Long.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val)))
  115.                     {
  116.                         val = Convert.toLong(val);
  117.                     }
  118.                     else if (Double.TYPE == fieldType || Double.class == fieldType)
  119.                     {
  120.                         val = Convert.toDouble(val);
  121.                     }
  122.                     else if (Float.TYPE == fieldType || Float.class == fieldType)
  123.                     {
  124.                         val = Convert.toFloat(val);
  125.                     }
  126.                     else if (BigDecimal.class == fieldType)
  127.                     {
  128.                         val = Convert.toBigDecimal(val);
  129.                     }
  130.                     else if (Date.class == fieldType)
  131.                     {
  132.                         if (val instanceof String)
  133.                         {
  134.                             val = DateUtils.parseDate(val);
  135.                         }
  136.                         else if (val instanceof Double)
  137.                         {
  138.                             val = DateUtil.getJavaDate((Double) val);
  139.                         }
  140.                     }
  141.                     else if (Boolean.TYPE == fieldType || Boolean.class == fieldType)
  142.                     {
  143.                         val = Convert.toBool(val, false);
  144.                     }
  145.                     if (StringUtils.isNotNull(fieldType))
  146.                     {
  147.                         String propertyName = field.getName();
  148.                         if (StringUtils.isNotEmpty(attr.targetAttr()))
  149.                         {
  150.                             propertyName = field.getName() + "." + attr.targetAttr();
  151.                         }
  152.                         if (StringUtils.isNotEmpty(attr.readConverterExp()))
  153.                         {
  154.                             val = reverseByExp(Convert.toStr(val), attr.readConverterExp(), attr.separator());
  155.                         }
  156.                         else if (StringUtils.isNotEmpty(attr.dictType()))
  157.                         {
  158.                             val = reverseDictByExp(Convert.toStr(val), attr.dictType(), attr.separator());
  159.                         }
  160.                         else if (!attr.handler().equals(ExcelHandlerAdapter.class))
  161.                         {
  162.                             val = dataFormatHandlerAdapter(val, attr, null);
  163.                         }
  164.                         else if (ColumnType.IMAGE == attr.cellType() && StringUtils.isNotEmpty(pictures))
  165.                         {
  166.                             //获取指定行指定列中的图片文件:从获取的文件集合中获取
  167.                             PictureData image = pictures.get(row.getRowNum() + "_" + entry.getKey());
  168.                             if (image == null)
  169.                             {
  170.                                 val = "";
  171.                             }
  172.                             else
  173.                             {
  174.                                 byte[] data = image.getData();
  175.                                 val = FileUtils.writeImportBytes(data);//图片文件写入到 application.yml文件 ruoyi.profile属性对应的文件目录下
  176.                             }
  177.                         }
  178.                         ReflectUtils.invokeSetter(entity, propertyName, val);
  179.                     }
  180.                 }
  181.                 list.add(entity);
  182.             }
  183.         }
  184.         return list;
  185.     }
复制代码



最终,工具类 ExcelUtil.java:
  1. package com.ruoyi.common.utils.poi;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.lang.reflect.ParameterizedType;import java.math.BigDecimal;import java.text.DecimalFormat;import java.time.LocalDate;import java.time.LocalDateTime;import java.util.ArrayList;import java.util.Arrays;import java.util.Collection;import java.util.Comparator;import java.util.Date;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Set;import java.util.UUID;import java.util.stream.Collectors;import javax.servlet.http.HttpServletResponse;import org.apache.commons.lang3.ArrayUtils;import org.apache.commons.lang3.RegExUtils;import org.apache.commons.lang3.reflect.FieldUtils;import org.apache.poi.hssf.usermodel.HSSFClientAnchor;import org.apache.poi.hssf.usermodel.HSSFPicture;import org.apache.poi.hssf.usermodel.HSSFPictureData;import org.apache.poi.hssf.usermodel.HSSFShape;import org.apache.poi.hssf.usermodel.HSSFSheet;import org.apache.poi.hssf.usermodel.HSSFWorkbook;import org.apache.poi.ooxml.POIXMLDocumentPart;import org.apache.poi.ss.usermodel.BorderStyle;import org.apache.poi.ss.usermodel.Cell;import org.apache.poi.ss.usermodel.CellStyle;import org.apache.poi.ss.usermodel.CellType;import org.apache.poi.ss.usermodel.ClientAnchor;import org.apache.poi.ss.usermodel.DataValidation;import org.apache.poi.ss.usermodel.DataValidationConstraint;import org.apache.poi.ss.usermodel.DataValidationHelper;import org.apache.poi.ss.usermodel.DateUtil;import org.apache.poi.ss.usermodel.Drawing;import org.apache.poi.ss.usermodel.FillPatternType;import org.apache.poi.ss.usermodel.Font;import org.apache.poi.ss.usermodel.HorizontalAlignment;import org.apache.poi.ss.usermodel.IndexedColors;import org.apache.poi.ss.usermodel.Name;import org.apache.poi.ss.usermodel.PictureData;import org.apache.poi.ss.usermodel.Row;import org.apache.poi.ss.usermodel.Sheet;import org.apache.poi.ss.usermodel.VerticalAlignment;import org.apache.poi.ss.usermodel.Workbook;import org.apache.poi.ss.usermodel.WorkbookFactory;import org.apache.poi.ss.util.CellRangeAddress;import org.apache.poi.ss.util.CellRangeAddressList;import org.apache.poi.util.IOUtils;import org.apache.poi.xssf.streaming.SXSSFWorkbook;import org.apache.poi.xssf.usermodel.XSSFClientAnchor;import org.apache.poi.xssf.usermodel.XSSFDataValidation;import org.apache.poi.xssf.usermodel.XSSFDrawing;import org.apache.poi.xssf.usermodel.XSSFPicture;import org.apache.poi.xssf.usermodel.XSSFShape;import org.apache.poi.xssf.usermodel.XSSFSheet;import org.apache.poi.xssf.usermodel.XSSFWorkbook;import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import com.ruoyi.common.annotation.Excel;import com.ruoyi.common.annotation.Excel.ColumnType;import com.ruoyi.common.annotation.Excel.Type;import com.ruoyi.common.annotation.Excels;import com.ruoyi.common.config.RuoYiConfig;import com.ruoyi.common.core.domain.AjaxResult;import com.ruoyi.common.core.text.Convert;import com.ruoyi.common.exception.UtilException;import com.ruoyi.common.utils.DateUtils;import com.ruoyi.common.utils.DictUtils;import com.ruoyi.common.utils.StringUtils;import com.ruoyi.common.utils.file.FileTypeUtils;import com.ruoyi.common.utils.file.FileUtils;import com.ruoyi.common.utils.file.ImageUtils;import com.ruoyi.common.utils.reflect.ReflectUtils;/** * Excel相干处理 *  * @author ruoyi */public class ExcelUtil<T>{    private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class);    public static final String FORMULA_REGEX_STR = "=|-|\\+|@";    public static final String[] FORMULA_STR = { "=", "-", "+", "@" };    /**     * 用于dictType属性数据存储,制止重复查缓存     */    public Map<String, String> sysDictMap = new HashMap<String, String>();    /**     * Excel sheet最大行数,默认65536     */    public static final int sheetSize = 65536;    /**     * 工作表名称     */    private String sheetName;    /**     * 导出范例(EXPORT:导出数据;IMPORT:导入模板)     */    private Type type;    /**     * 工作薄对象     */    private Workbook wb;    /**     * 工作表对象     */    private Sheet sheet;    /**     * 样式列表     */    private Map<String, CellStyle> styles;    /**     * 导入导出数据列表     */    private List<T> list;    /**     * 注解列表     */    private List<Object[]> fields;    /**     * 当前行号     */    private int rownum;    /**     * 标题     */    private String title;    /**     * 最大高度     */    private short maxHeight;    /**     * 归并后末了行数     */    private int subMergedLastRowNum = 0;    /**     * 归并后开始行数     */    private int subMergedFirstRowNum = 1;    /**     * 对象的子列表方法     */    private Method subMethod;    /**     * 对象的子列表属性     */    private List<Field> subFields;    /**     * 统计列表     */    private Map<Integer, Double> statistics = new HashMap<Integer, Double>();    /**     * 数字格式     */    private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00");    /**     * 实体对象     */    public Class<T> clazz;    /**     * 需要排除列属性     */    public String[] excludeFields;    public ExcelUtil(Class<T> clazz)    {        this.clazz = clazz;    }    /**     * 潜伏Excel中列属性     *     * @param fields 列属性名 示例[单个"name"/多个"id","name"]     * @throws Exception     */    public void hideColumn(String... fields)    {        this.excludeFields = fields;    }    public void init(List<T> list, String sheetName, String title, Type type)    {        if (list == null)        {            list = new ArrayList<T>();        }        this.list = list;        this.sheetName = sheetName;        this.type = type;        this.title = title;        createExcelField();        createWorkbook();        createTitle();        createSubHead();    }    /**     * 创建excel第一行标题     */    public void createTitle()    {        if (StringUtils.isNotEmpty(title))        {            subMergedFirstRowNum++;            subMergedLastRowNum++;            int titleLastCol = this.fields.size() - 1;            if (isSubList())            {                titleLastCol = titleLastCol + subFields.size() - 1;            }            Row titleRow = sheet.createRow(rownum == 0 ? rownum++ : 0);            titleRow.setHeightInPoints(30);            Cell titleCell = titleRow.createCell(0);            titleCell.setCellStyle(styles.get("title"));            titleCell.setCellValue(title);            sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), titleRow.getRowNum(), titleRow.getRowNum(), titleLastCol));        }    }    /**     * 创建对象的子列表名称     */    public void createSubHead()    {        if (isSubList())        {            subMergedFirstRowNum++;            subMergedLastRowNum++;            Row subRow = sheet.createRow(rownum);            int excelNum = 0;            for (Object[] objects : fields)            {                Excel attr = (Excel) objects[1];                Cell headCell1 = subRow.createCell(excelNum);                headCell1.setCellValue(attr.name());                headCell1.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor())));                excelNum++;            }            int headFirstRow = excelNum - 1;            int headLastRow = headFirstRow + subFields.size() - 1;            if (headLastRow > headFirstRow)            {                sheet.addMergedRegion(new CellRangeAddress(rownum, rownum, headFirstRow, headLastRow));            }            rownum++;        }    }    /**     * 对excel表单默认第一个索引名转换成list     *      * @param is 输入流     * @return 转换后聚集     */    public List<T> importExcel(InputStream is)    {        List<T> list = null;        try        {            list = importExcel(is, 0);        }        catch (Exception e)        {            log.error("导入Excel非常{}", e.getMessage());            throw new UtilException(e.getMessage());        }        finally        {            IOUtils.closeQuietly(is);        }        return list;    }    /**     * 对excel表单默认第一个索引名转换成list     *      * @param is 输入流     * @param titleNum 标题占用行数     * @return 转换后聚集     */    public List<T> importExcel(InputStream is, int titleNum) throws Exception    {        return importExcel(StringUtils.EMPTY, is, titleNum);    }    /**     * 对excel表单指定表格索引名转换成list     *      * @param sheetName 表格索引名     * @param titleNum 标题占用行数     * @param is 输入流     * @return 转换后聚集     */    public List<T> importExcel(String sheetName, InputStream is, int titleNum) throws Exception    {        this.type = Type.IMPORT;        this.wb = WorkbookFactory.create(is);        List<T> list = new ArrayList<T>();        // 如果指定sheet名,则取指定sheet中的内容 否则默认指向第1个sheet        Sheet sheet = StringUtils.isNotEmpty(sheetName) ? wb.getSheet(sheetName) : wb.getSheetAt(0);        if (sheet == null)        {            throw new IOException("文件sheet不存在");        }        boolean isXSSFWorkbook = !(wb instanceof HSSFWorkbook);        //获取文档指定sheet中所有图片:图片位置、文件流        Map<String, PictureData> pictures;        if (isXSSFWorkbook)        {            pictures = getSheetPictures07((XSSFSheet) sheet, (XSSFWorkbook) wb);        }        else        {            pictures = getSheetPictures03((HSSFSheet) sheet, (HSSFWorkbook) wb);        }        // 获取末了一个非空行的行下标,好比总行数为n,则返回的为n-1        int rows = sheet.getLastRowNum();        if (rows > 0)        {            // 界说一个map用于存放excel列的序号和field.            Map<String, Integer> cellMap = new HashMap<String, Integer>();            // 获取表头            Row heard = sheet.getRow(titleNum);            for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++)            {                Cell cell = heard.getCell(i);                if (StringUtils.isNotNull(cell))                {                    String value = this.getCellValue(heard, i).toString();                    cellMap.put(value, i);                }                else                {                    cellMap.put(null, i);                }            }            // 有数据时才处理 得到类的所有field.            List<Object[]> fields = this.getFields();            Map<Integer, Object[]> fieldsMap = new HashMap<Integer, Object[]>();            for (Object[] objects : fields)            {                Excel attr = (Excel) objects[1];                Integer column = cellMap.get(attr.name());                if (column != null)                {                    fieldsMap.put(column, objects);                }            }            for (int i = titleNum + 1; i <= rows; i++)            {                // 从第2行开始取数据,默认第一行是表头.                Row row = sheet.getRow(i);                // 判断当前行是否是空行                if (isRowEmpty(row))                {                    continue;                }                T entity = null;                //遍历所有列 逐列字段值获取并赋值给entity对象的各属性                for (Map.Entry<Integer, Object[]> entry : fieldsMap.entrySet())                {                    Object val = this.getCellValue(row, entry.getKey());//获取当前列 默认值                    // ============== 新增 归并行相干代码块 ================                    // 判断是否归并行  isMergedRow(sheet, rowNum, column):是归并行,则获取归并行数据 重新赋值给当前列                    if (isMergedRow(sheet, i, entry.getKey())) val = getMergedRegionValue(sheet, i, entry.getKey());                    // ============== 新增 归并行相干代码块 ================                    // 如果不存在实例则新建.                    entity = (entity == null ? clazz.newInstance() : entity);                    // 从map中得到对应列的field.                    Field field = (Field) entry.getValue()[0];                    Excel attr = (Excel) entry.getValue()[1];                    // 取得范例,并根据对象范例设置值.                    Class<?> fieldType = field.getType();                    if (String.class == fieldType)                    {                        String s = Convert.toStr(val);                        if (StringUtils.endsWith(s, ".0"))                        {                            val = StringUtils.substringBefore(s, ".0");                        }                        else                        {                            String dateFormat = field.getAnnotation(Excel.class).dateFormat();                            if (StringUtils.isNotEmpty(dateFormat))                            {                                val = parseDateToStr(dateFormat, val);                            }                            else                            {                                val = Convert.toStr(val);                            }                        }                    }                    else if ((Integer.TYPE == fieldType || Integer.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val)))                    {                        val = Convert.toInt(val);                    }                    else if ((Long.TYPE == fieldType || Long.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val)))                    {                        val = Convert.toLong(val);                    }                    else if (Double.TYPE == fieldType || Double.class == fieldType)                    {                        val = Convert.toDouble(val);                    }                    else if (Float.TYPE == fieldType || Float.class == fieldType)                    {                        val = Convert.toFloat(val);                    }                    else if (BigDecimal.class == fieldType)                    {                        val = Convert.toBigDecimal(val);                    }                    else if (Date.class == fieldType)                    {                        if (val instanceof String)                        {                            val = DateUtils.parseDate(val);                        }                        else if (val instanceof Double)                        {                            val = DateUtil.getJavaDate((Double) val);                        }                    }                    else if (Boolean.TYPE == fieldType || Boolean.class == fieldType)                    {                        val = Convert.toBool(val, false);                    }                    if (StringUtils.isNotNull(fieldType))                    {                        String propertyName = field.getName();                        if (StringUtils.isNotEmpty(attr.targetAttr()))                        {                            propertyName = field.getName() + "." + attr.targetAttr();                        }                        if (StringUtils.isNotEmpty(attr.readConverterExp()))                        {                            val = reverseByExp(Convert.toStr(val), attr.readConverterExp(), attr.separator());                        }                        else if (StringUtils.isNotEmpty(attr.dictType()))                        {                            val = reverseDictByExp(Convert.toStr(val), attr.dictType(), attr.separator());                        }                        else if (!attr.handler().equals(ExcelHandlerAdapter.class))                        {                            val = dataFormatHandlerAdapter(val, attr, null);                        }                        else if (ColumnType.IMAGE == attr.cellType() && StringUtils.isNotEmpty(pictures))                        {                            PictureData image = pictures.get(row.getRowNum() + "_" + entry.getKey());                            if (image == null)                            {                                val = "";                            }                            else                            {                                byte[] data = image.getData();                                val = FileUtils.writeImportBytes(data);//图片文件写入到 application.yml文件 ruoyi.profile属性对应的文件目次下                            }                        }                        ReflectUtils.invokeSetter(entity, propertyName, val);                    }                }                list.add(entity);            }        }        return list;    }    /**     * 新增 归并行相干代码:判断是否是归并行     *     * @param sheet     * @param row     * @param column     * @return     */    private boolean isMergedRow(Sheet sheet, int row, int column) {        int sheetMergeCount = sheet.getNumMergedRegions();        for (int i = 0; i < sheetMergeCount; i++) {            CellRangeAddress cellAddresses = sheet.getMergedRegion(i);            int firstColumn = cellAddresses.getFirstColumn();            int lastColumn = cellAddresses.getLastColumn();            int firstRow = cellAddresses.getFirstRow();            int lastRow = cellAddresses.getLastRow();            if (row >= firstRow && row <= lastRow) {                if (column >= firstColumn && column <= lastColumn) {                    return true;                }            }        }        return false;    }    /**
  2.      * 新增 合并行相关代码:获取合并行的数据
  3.      *
  4.      * @param sheet
  5.      * @param row
  6.      * @param column
  7.      * @return
  8.      */
  9.     private String getMergedRegionValue(Sheet sheet, int row, int column) {
  10.         // 获得该sheet所有合并单元格数量
  11.         int sheetMergeCount = sheet.getNumMergedRegions();
  12.         for (int i = 0; i < sheetMergeCount; i++) {
  13.             // 获得合并区域
  14.             CellRangeAddress cellAddresses = sheet.getMergedRegion(i);
  15.             int firstColumn = cellAddresses.getFirstColumn();
  16.             int lastColumn = cellAddresses.getLastColumn();
  17.             int firstRow = cellAddresses.getFirstRow();
  18.             int lastRow = cellAddresses.getLastRow();
  19.             /*判断传入的单元格的行号列号是否在合并单元格的范围内,
  20.             如果在合并单元格的范围内,择返回合并区域的首单元格格值
  21.              */
  22.             if (row >= firstRow && row <= lastRow) {
  23.                 if (column >= firstColumn && column <= lastColumn) {
  24.                     Row firRow = sheet.getRow(firstRow);
  25.                     /* 合并行使用的获取单元格内容方法
  26.                     Cell firCell = firRow.getCell(firstColumn);
  27.                     return getCellValue(firCell);
  28.                      */
  29.                     return getCellValue(firRow, firstColumn).toString();//改为使用 若依自带获取单元格内容方法
  30.                 }
  31.             }
  32.         }
  33.         // 如果该单元格行号列号不在任何一个合并区域,则返回null
  34.         return null;
  35.     }    /**     * 对list数据源将其内里的数据导入到excel表单     *      * @param list 导出数据聚集     * @param sheetName 工作表的名称     * @return 结果     */    public AjaxResult exportExcel(List<T> list, String sheetName)    {        return exportExcel(list, sheetName, StringUtils.EMPTY);    }    /**     * 对list数据源将其内里的数据导入到excel表单     *      * @param list 导出数据聚集     * @param sheetName 工作表的名称     * @param title 标题     * @return 结果     */    public AjaxResult exportExcel(List<T> list, String sheetName, String title)    {        this.init(list, sheetName, title, Type.EXPORT);        return exportExcel();    }    /**     * 对list数据源将其内里的数据导入到excel表单     *      * @param response 返回数据     * @param list 导出数据聚集     * @param sheetName 工作表的名称     * @return 结果     */    public void exportExcel(HttpServletResponse response, List<T> list, String sheetName)    {        exportExcel(response, list, sheetName, StringUtils.EMPTY);    }    /**     * 对list数据源将其内里的数据导入到excel表单     *      * @param response 返回数据     * @param list 导出数据聚集     * @param sheetName 工作表的名称     * @param title 标题     * @return 结果     */    public void exportExcel(HttpServletResponse response, List<T> list, String sheetName, String title)    {        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");        response.setCharacterEncoding("utf-8");        this.init(list, sheetName, title, Type.EXPORT);        exportExcel(response);    }    /**     * 对list数据源将其内里的数据导入到excel表单     *      * @param sheetName 工作表的名称     * @return 结果     */    public AjaxResult importTemplateExcel(String sheetName)    {        return importTemplateExcel(sheetName, StringUtils.EMPTY);    }    /**     * 对list数据源将其内里的数据导入到excel表单     *      * @param sheetName 工作表的名称     * @param title 标题     * @return 结果     */    public AjaxResult importTemplateExcel(String sheetName, String title)    {        this.init(null, sheetName, title, Type.IMPORT);        return exportExcel();    }    /**     * 对list数据源将其内里的数据导入到excel表单     *      * @param sheetName 工作表的名称     * @return 结果     */    public void importTemplateExcel(HttpServletResponse response, String sheetName)    {        importTemplateExcel(response, sheetName, StringUtils.EMPTY);    }    /**     * 对list数据源将其内里的数据导入到excel表单     *      * @param sheetName 工作表的名称     * @param title 标题     * @return 结果     */    public void importTemplateExcel(HttpServletResponse response, String sheetName, String title)    {        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");        response.setCharacterEncoding("utf-8");        this.init(null, sheetName, title, Type.IMPORT);        exportExcel(response);    }    /**     * 对list数据源将其内里的数据导入到excel表单     *      * @return 结果     */    public void exportExcel(HttpServletResponse response)    {        try        {            writeSheet();            wb.write(response.getOutputStream());        }        catch (Exception e)        {            log.error("导出Excel非常{}", e.getMessage());        }        finally        {            IOUtils.closeQuietly(wb);        }    }    /**     * 对list数据源将其内里的数据导入到excel表单     *      * @return 结果     */    public AjaxResult exportExcel()    {        OutputStream out = null;        try        {            writeSheet();            String filename = encodingFilename(sheetName);            out = new FileOutputStream(getAbsoluteFile(filename));            wb.write(out);            return AjaxResult.success(filename);        }        catch (Exception e)        {            log.error("导出Excel非常{}", e.getMessage());            throw new UtilException("导出Excel失败,请联系网站管理员!");        }        finally        {            IOUtils.closeQuietly(wb);            IOUtils.closeQuietly(out);        }    }    /**     * 创建写入数据到Sheet     */    public void writeSheet()    {        // 取出一共有多少个sheet.        int sheetNo = Math.max(1, (int) Math.ceil(list.size() * 1.0 / sheetSize));        for (int index = 0; index < sheetNo; index++)        {            createSheet(sheetNo, index);            // 产生一行            Row row = sheet.createRow(rownum);            int column = 0;            // 写入各个字段的列头名称            for (Object[] os : fields)            {                Field field = (Field) os[0];                Excel excel = (Excel) os[1];                if (Collection.class.isAssignableFrom(field.getType()))                {                    for (Field subField : subFields)                    {                        Excel subExcel = subField.getAnnotation(Excel.class);                        this.createHeadCell(subExcel, row, column++);                    }                }                else                {                    this.createHeadCell(excel, row, column++);                }            }            if (Type.EXPORT.equals(type))            {                fillExcelData(index, row);                addStatisticsRow();            }        }    }    /**     * 填充excel数据     *      * @param index 序号     * @param row 单位格行     */    @SuppressWarnings("unchecked")    public void fillExcelData(int index, Row row)    {        int startNo = index * sheetSize;        int endNo = Math.min(startNo + sheetSize, list.size());        int rowNo = (1 + rownum) - startNo;        for (int i = startNo; i < endNo; i++)        {            rowNo = isSubList() ? (i > 1 ? rowNo + 1 : rowNo + i) : i + 1 + rownum - startNo;            row = sheet.createRow(rowNo);            // 得到导出对象.            T vo = (T) list.get(i);            Collection<?> subList = null;            if (isSubList())            {                if (isSubListValue(vo))                {                    subList = getListCellValue(vo);                    subMergedLastRowNum = subMergedLastRowNum + subList.size();                }                else                {                    subMergedFirstRowNum++;                    subMergedLastRowNum++;                }            }            int column = 0;            for (Object[] os : fields)            {                Field field = (Field) os[0];                Excel excel = (Excel) os[1];                if (Collection.class.isAssignableFrom(field.getType()) && StringUtils.isNotNull(subList))                {                    boolean subFirst = false;                    for (Object obj : subList)                    {                        if (subFirst)                        {                            rowNo++;                            row = sheet.createRow(rowNo);                        }                        List<Field> subFields = FieldUtils.getFieldsListWithAnnotation(obj.getClass(), Excel.class);                        int subIndex = 0;                        for (Field subField : subFields)                        {                            if (subField.isAnnotationPresent(Excel.class))                            {                                subField.setAccessible(true);                                Excel attr = subField.getAnnotation(Excel.class);                                this.addCell(attr, row, (T) obj, subField, column + subIndex);                            }                            subIndex++;                        }                        subFirst = true;                    }                    this.subMergedFirstRowNum = this.subMergedFirstRowNum + subList.size();                }                else                {                    this.addCell(excel, row, vo, field, column++);                }            }        }    }    /**     * 创建表格样式     *      * @param wb 工作薄对象     * @return 样式列表     */    private Map<String, CellStyle> createStyles(Workbook wb)    {        // 写入各条记录,每条记录对应excel表中的一行        Map<String, CellStyle> styles = new HashMap<String, CellStyle>();        CellStyle style = wb.createCellStyle();        style.setAlignment(HorizontalAlignment.CENTER);        style.setVerticalAlignment(VerticalAlignment.CENTER);        Font titleFont = wb.createFont();        titleFont.setFontName("Arial");        titleFont.setFontHeightInPoints((short) 16);        titleFont.setBold(true);        style.setFont(titleFont);        styles.put("title", style);        style = wb.createCellStyle();        style.setAlignment(HorizontalAlignment.CENTER);        style.setVerticalAlignment(VerticalAlignment.CENTER);        style.setBorderRight(BorderStyle.THIN);        style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());        style.setBorderLeft(BorderStyle.THIN);        style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());        style.setBorderTop(BorderStyle.THIN);        style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());        style.setBorderBottom(BorderStyle.THIN);        style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());        Font dataFont = wb.createFont();        dataFont.setFontName("Arial");        dataFont.setFontHeightInPoints((short) 10);        style.setFont(dataFont);        styles.put("data", style);        style = wb.createCellStyle();        style.setAlignment(HorizontalAlignment.CENTER);        style.setVerticalAlignment(VerticalAlignment.CENTER);        Font totalFont = wb.createFont();        totalFont.setFontName("Arial");        totalFont.setFontHeightInPoints((short) 10);        style.setFont(totalFont);        styles.put("total", style);        styles.putAll(annotationHeaderStyles(wb, styles));        styles.putAll(annotationDataStyles(wb));        return styles;    }    /**     * 根据Excel注解创建表格头样式     *      * @param wb 工作薄对象     * @return 自界说样式列表     */    private Map<String, CellStyle> annotationHeaderStyles(Workbook wb, Map<String, CellStyle> styles)    {        Map<String, CellStyle> headerStyles = new HashMap<String, CellStyle>();        for (Object[] os : fields)        {            Excel excel = (Excel) os[1];            String key = StringUtils.format("header_{}_{}", excel.headerColor(), excel.headerBackgroundColor());            if (!headerStyles.containsKey(key))            {                CellStyle style = wb.createCellStyle();                style.cloneStyleFrom(styles.get("data"));                style.setAlignment(HorizontalAlignment.CENTER);                style.setVerticalAlignment(VerticalAlignment.CENTER);                style.setFillForegroundColor(excel.headerBackgroundColor().index);                style.setFillPattern(FillPatternType.SOLID_FOREGROUND);                Font headerFont = wb.createFont();                headerFont.setFontName("Arial");                headerFont.setFontHeightInPoints((short) 10);                headerFont.setBold(true);                headerFont.setColor(excel.headerColor().index);                style.setFont(headerFont);                headerStyles.put(key, style);            }        }        return headerStyles;    }    /**     * 根据Excel注解创建表格列样式     *      * @param wb 工作薄对象     * @return 自界说样式列表     */    private Map<String, CellStyle> annotationDataStyles(Workbook wb)    {        Map<String, CellStyle> styles = new HashMap<String, CellStyle>();        for (Object[] os : fields)        {            Excel excel = (Excel) os[1];            String key = StringUtils.format("data_{}_{}_{}", excel.align(), excel.color(), excel.backgroundColor());            if (!styles.containsKey(key))            {                CellStyle style = wb.createCellStyle();                style.setAlignment(excel.align());                style.setVerticalAlignment(VerticalAlignment.CENTER);                style.setBorderRight(BorderStyle.THIN);                style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());                style.setBorderLeft(BorderStyle.THIN);                style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());                style.setBorderTop(BorderStyle.THIN);                style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());                style.setBorderBottom(BorderStyle.THIN);                style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());                style.setFillPattern(FillPatternType.SOLID_FOREGROUND);                style.setFillForegroundColor(excel.backgroundColor().getIndex());                Font dataFont = wb.createFont();                dataFont.setFontName("Arial");                dataFont.setFontHeightInPoints((short) 10);                dataFont.setColor(excel.color().index);                style.setFont(dataFont);                styles.put(key, style);            }        }        return styles;    }    /**     * 创建单位格     */    public Cell createHeadCell(Excel attr, Row row, int column)    {        // 创建列        Cell cell = row.createCell(column);        // 写入列信息        cell.setCellValue(attr.name());        setDataValidation(attr, row, column);        cell.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor())));        if (isSubList())        {            // 填充默认样式,防止归并单位格样式失效            sheet.setDefaultColumnStyle(column, styles.get(StringUtils.format("data_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor())));            if (attr.needMerge())            {                sheet.addMergedRegion(new CellRangeAddress(rownum - 1, rownum, column, column));            }        }        return cell;    }    /**     * 设置单位格信息     *      * @param value 单位格值     * @param attr 注解相干     * @param cell 单位格信息     */    public void setCellVo(Object value, Excel attr, Cell cell)    {        if (ColumnType.STRING == attr.cellType())        {            String cellValue = Convert.toStr(value);            // 对于任何以表达式触发字符 =-+@开头的单位格,直接使用tab字符作为前缀,防止CSV注入。            if (StringUtils.startsWithAny(cellValue, FORMULA_STR))            {                cellValue = RegExUtils.replaceFirst(cellValue, FORMULA_REGEX_STR, "\t$0");            }            if (value instanceof Collection && StringUtils.equals("[]", cellValue))            {                cellValue = StringUtils.EMPTY;            }            cell.setCellValue(StringUtils.isNull(cellValue) ? attr.defaultValue() : cellValue + attr.suffix());        }        else if (ColumnType.NUMERIC == attr.cellType())        {            if (StringUtils.isNotNull(value))            {                cell.setCellValue(StringUtils.contains(Convert.toStr(value), ".") ? Convert.toDouble(value) : Convert.toInt(value));            }        }        else if (ColumnType.IMAGE == attr.cellType())        {            ClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1), cell.getRow().getRowNum() + 1);            String imagePath = Convert.toStr(value);            if (StringUtils.isNotEmpty(imagePath))            {                byte[] data = ImageUtils.getImage(imagePath);                getDrawingPatriarch(cell.getSheet()).createPicture(anchor,                        cell.getSheet().getWorkbook().addPicture(data, getImageType(data)));            }        }    }    /**     * 获取画布     */    public static Drawing<?> getDrawingPatriarch(Sheet sheet)    {        if (sheet.getDrawingPatriarch() == null)        {            sheet.createDrawingPatriarch();        }        return sheet.getDrawingPatriarch();    }    /**     * 获取图片范例,设置图片插入范例     */    public int getImageType(byte[] value)    {        String type = FileTypeUtils.getFileExtendName(value);        if ("JPG".equalsIgnoreCase(type))        {            return Workbook.PICTURE_TYPE_JPEG;        }        else if ("PNG".equalsIgnoreCase(type))        {            return Workbook.PICTURE_TYPE_PNG;        }        return Workbook.PICTURE_TYPE_JPEG;    }    /**     * 创建表格样式     */    public void setDataValidation(Excel attr, Row row, int column)    {        if (attr.name().indexOf("注:") >= 0)        {            sheet.setColumnWidth(column, 6000);        }        else        {            // 设置列宽            sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256));        }        if (StringUtils.isNotEmpty(attr.prompt()) || attr.combo().length > 0)        {            if (attr.combo().length > 15 || StringUtils.join(attr.combo()).length() > 255)            {                // 如果下拉数大于15或字符串长度大于255,则使用一个新sheet存储,制止生成的模板下拉值获取不到                setXSSFValidationWithHidden(sheet, attr.combo(), attr.prompt(), 1, 100, column, column);            }            else            {                // 提示信息或只能选择不能输入的列内容.                setPromptOrValidation(sheet, attr.combo(), attr.prompt(), 1, 100, column, column);            }        }    }    /**     * 添加单位格     */    public Cell addCell(Excel attr, Row row, T vo, Field field, int column)    {        Cell cell = null;        try        {            // 设置行高            row.setHeight(maxHeight);            // 根据Excel中设置环境决定是否导出,有些环境需要保持为空,希望用户填写这一列.            if (attr.isExport())            {                // 创建cell                cell = row.createCell(column);                if (isSubListValue(vo) && getListCellValue(vo).size() > 1 && attr.needMerge())                {                    CellRangeAddress cellAddress = new CellRangeAddress(subMergedFirstRowNum, subMergedLastRowNum, column, column);                    sheet.addMergedRegion(cellAddress);                }                cell.setCellStyle(styles.get(StringUtils.format("data_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor())));                // 用于读取对象中的属性                Object value = getTargetValue(vo, field, attr);                String dateFormat = attr.dateFormat();                String readConverterExp = attr.readConverterExp();                String separator = attr.separator();                String dictType = attr.dictType();                if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value))                {                    cell.setCellValue(parseDateToStr(dateFormat, value));                }                else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value))                {                    cell.setCellValue(convertByExp(Convert.toStr(value), readConverterExp, separator));                }                else if (StringUtils.isNotEmpty(dictType) && StringUtils.isNotNull(value))                {                    if (!sysDictMap.containsKey(dictType + value))                    {                        String lable = convertDictByExp(Convert.toStr(value), dictType, separator);                        sysDictMap.put(dictType + value, lable);                    }                    cell.setCellValue(sysDictMap.get(dictType + value));                }                else if (value instanceof BigDecimal && -1 != attr.scale())                {                    cell.setCellValue((((BigDecimal) value).setScale(attr.scale(), attr.roundingMode())).doubleValue());                }                else if (!attr.handler().equals(ExcelHandlerAdapter.class))                {                    cell.setCellValue(dataFormatHandlerAdapter(value, attr, cell));                }                else                {                    // 设置列范例                    setCellVo(value, attr, cell);                }                addStatisticsData(column, Convert.toStr(value), attr);            }        }        catch (Exception e)        {            log.error("导出Excel失败{}", e);        }        return cell;    }    /**     * 设置 POI XSSFSheet 单位格提示或选择框     *      * @param sheet 表单     * @param textlist 下拉框显示的内容     * @param promptContent 提示内容     * @param firstRow 开始行     * @param endRow 结束行     * @param firstCol 开始列     * @param endCol 结束列     */    public void setPromptOrValidation(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow,            int firstCol, int endCol)    {        DataValidationHelper helper = sheet.getDataValidationHelper();        DataValidationConstraint constraint = textlist.length > 0 ? helper.createExplicitListConstraint(textlist) : helper.createCustomConstraint("DD1");        CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol);        DataValidation dataValidation = helper.createValidation(constraint, regions);        if (StringUtils.isNotEmpty(promptContent))        {            // 如果设置了提示信息则鼠标放上去提示            dataValidation.createPromptBox("", promptContent);            dataValidation.setShowPromptBox(true);        }        // 处理Excel兼容性题目        if (dataValidation instanceof XSSFDataValidation)        {            dataValidation.setSuppressDropDownArrow(true);            dataValidation.setShowErrorBox(true);        }        else        {            dataValidation.setSuppressDropDownArrow(false);        }        sheet.addValidationData(dataValidation);    }    /**     * 设置某些列的值只能输入预制的数据,显示下拉框(兼容超出一定数量的下拉框).     *      * @param sheet 要设置的sheet.     * @param textlist 下拉框显示的内容     * @param promptContent 提示内容     * @param firstRow 开始行     * @param endRow 结束行     * @param firstCol 开始列     * @param endCol 结束列     */    public void setXSSFValidationWithHidden(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow, int firstCol, int endCol)    {        String hideSheetName = "combo_" + firstCol + "_" + endCol;        Sheet hideSheet = wb.createSheet(hideSheetName); // 用于存储 下拉菜单数据        for (int i = 0; i < textlist.length; i++)        {            hideSheet.createRow(i).createCell(0).setCellValue(textlist[i]);        }        // 创建名称,可被其他单位格引用        Name name = wb.createName();        name.setNameName(hideSheetName + "_data");        name.setRefersToFormula(hideSheetName + "!$A$1:$A$" + textlist.length);        DataValidationHelper helper = sheet.getDataValidationHelper();        // 加载下拉列表内容        DataValidationConstraint constraint = helper.createFormulaListConstraint(hideSheetName + "_data");        // 设置数据有效性加载在哪个单位格上,四个参数分别是:起始行、终止行、起始列、终止列        CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol);        // 数据有效性对象        DataValidation dataValidation = helper.createValidation(constraint, regions);        if (StringUtils.isNotEmpty(promptContent))        {            // 如果设置了提示信息则鼠标放上去提示            dataValidation.createPromptBox("", promptContent);            dataValidation.setShowPromptBox(true);        }        // 处理Excel兼容性题目        if (dataValidation instanceof XSSFDataValidation)        {            dataValidation.setSuppressDropDownArrow(true);            dataValidation.setShowErrorBox(true);        }        else        {            dataValidation.setSuppressDropDownArrow(false);        }        sheet.addValidationData(dataValidation);        // 设置hiddenSheet潜伏        wb.setSheetHidden(wb.getSheetIndex(hideSheet), true);    }    /**     * 分析导出值 0=男,1=女,2=未知     *      * @param propertyValue 参数值     * @param converterExp 翻译注解     * @param separator 分隔符     * @return 分析后值     */    public static String convertByExp(String propertyValue, String converterExp, String separator)    {        StringBuilder propertyString = new StringBuilder();        String[] convertSource = converterExp.split(",");        for (String item : convertSource)        {            String[] itemArray = item.split("=");            if (StringUtils.containsAny(propertyValue, separator))            {                for (String value : propertyValue.split(separator))                {                    if (itemArray[0].equals(value))                    {                        propertyString.append(itemArray[1] + separator);                        break;                    }                }            }            else            {                if (itemArray[0].equals(propertyValue))                {                    return itemArray[1];                }            }        }        return StringUtils.stripEnd(propertyString.toString(), separator);    }    /**     * 反向分析值 男=0,女=1,未知=2     *      * @param propertyValue 参数值     * @param converterExp 翻译注解     * @param separator 分隔符     * @return 分析后值     */    public static String reverseByExp(String propertyValue, String converterExp, String separator)    {        StringBuilder propertyString = new StringBuilder();        String[] convertSource = converterExp.split(",");        for (String item : convertSource)        {            String[] itemArray = item.split("=");            if (StringUtils.containsAny(propertyValue, separator))            {                for (String value : propertyValue.split(separator))                {                    if (itemArray[1].equals(value))                    {                        propertyString.append(itemArray[0] + separator);                        break;                    }                }            }            else            {                if (itemArray[1].equals(propertyValue))                {                    return itemArray[0];                }            }        }        return StringUtils.stripEnd(propertyString.toString(), separator);    }    /**     * 分析字典值     *      * @param dictValue 字典值     * @param dictType 字典范例     * @param separator 分隔符     * @return 字典标签     */    public static String convertDictByExp(String dictValue, String dictType, String separator)    {        return DictUtils.getDictLabel(dictType, dictValue, separator);    }    /**     * 反向分析值字典值     *      * @param dictLabel 字典标签     * @param dictType 字典范例     * @param separator 分隔符     * @return 字典值     */    public static String reverseDictByExp(String dictLabel, String dictType, String separator)    {        return DictUtils.getDictValue(dictType, dictLabel, separator);    }    /**     * 数据处理器     *      * @param value 数据值     * @param excel 数据注解     * @return     */    public String dataFormatHandlerAdapter(Object value, Excel excel, Cell cell)    {        try        {            Object instance = excel.handler().newInstance();            Method formatMethod = excel.handler().getMethod("format", new Class[] { Object.class, String[].class, Cell.class, Workbook.class });            value = formatMethod.invoke(instance, value, excel.args(), cell, this.wb);        }        catch (Exception e)        {            log.error("不能格式化数据 " + excel.handler(), e.getMessage());        }        return Convert.toStr(value);    }    /**     * 合计统计信息     */    private void addStatisticsData(Integer index, String text, Excel entity)    {        if (entity != null && entity.isStatistics())        {            Double temp = 0D;            if (!statistics.containsKey(index))            {                statistics.put(index, temp);            }            try            {                temp = Double.valueOf(text);            }            catch (NumberFormatException e)            {            }            statistics.put(index, statistics.get(index) + temp);        }    }    /**     * 创建统计行     */    public void addStatisticsRow()    {        if (statistics.size() > 0)        {            Row row = sheet.createRow(sheet.getLastRowNum() + 1);            Set<Integer> keys = statistics.keySet();            Cell cell = row.createCell(0);            cell.setCellStyle(styles.get("total"));            cell.setCellValue("合计");            for (Integer key : keys)            {                cell = row.createCell(key);                cell.setCellStyle(styles.get("total"));                cell.setCellValue(DOUBLE_FORMAT.format(statistics.get(key)));            }            statistics.clear();        }    }    /**     * 编码文件名     */    public String encodingFilename(String filename)    {        filename = UUID.randomUUID() + "_" + filename + ".xlsx";        return filename;    }    /**     * 获取下载路径     *      * @param filename 文件名称     */    public String getAbsoluteFile(String filename)    {        String downloadPath = RuoYiConfig.getDownloadPath() + filename;        File desc = new File(downloadPath);        if (!desc.getParentFile().exists())        {            desc.getParentFile().mkdirs();        }        return downloadPath;    }    /**     * 获取bean中的属性值     *      * @param vo 实体对象     * @param field 字段     * @param excel 注解     * @return 最终的属性值     * @throws Exception     */    private Object getTargetValue(T vo, Field field, Excel excel) throws Exception    {        Object o = field.get(vo);        if (StringUtils.isNotEmpty(excel.targetAttr()))        {            String target = excel.targetAttr();            if (target.contains("."))            {                String[] targets = target.split("[.]");                for (String name : targets)                {                    o = getValue(o, name);                }            }            else            {                o = getValue(o, target);            }        }        return o;    }    /**     * 以类的属性的get方法方法情势获取值     *      * @param o     * @param name     * @return value     * @throws Exception     */    private Object getValue(Object o, String name) throws Exception    {        if (StringUtils.isNotNull(o) && StringUtils.isNotEmpty(name))        {            Class<?> clazz = o.getClass();            Field field = clazz.getDeclaredField(name);            field.setAccessible(true);            o = field.get(o);        }        return o;    }    /**     * 得到所有界说字段     */    private void createExcelField()    {        this.fields = getFields();        this.fields = this.fields.stream().sorted(Comparator.comparing(objects -> ((Excel) objects[1]).sort())).collect(Collectors.toList());        this.maxHeight = getRowHeight();    }    /**     * 获取字段注解信息     */    public List<Object[]> getFields()    {        List<Object[]> fields = new ArrayList<Object[]>();        List<Field> tempFields = new ArrayList<>();        tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields()));        tempFields.addAll(Arrays.asList(clazz.getDeclaredFields()));        for (Field field : tempFields)        {            if (!ArrayUtils.contains(this.excludeFields, field.getName()))            {                // 单注解                if (field.isAnnotationPresent(Excel.class))                {                    Excel attr = field.getAnnotation(Excel.class);                    if (attr != null && (attr.type() == Type.ALL || attr.type() == type))                    {                        field.setAccessible(true);                        fields.add(new Object[] { field, attr });                    }                    if (Collection.class.isAssignableFrom(field.getType()))                    {                        subMethod = getSubMethod(field.getName(), clazz);                        ParameterizedType pt = (ParameterizedType) field.getGenericType();                        Class<?> subClass = (Class<?>) pt.getActualTypeArguments()[0];                        this.subFields = FieldUtils.getFieldsListWithAnnotation(subClass, Excel.class);                    }                }                // 多注解                if (field.isAnnotationPresent(Excels.class))                {                    Excels attrs = field.getAnnotation(Excels.class);                    Excel[] excels = attrs.value();                    for (Excel attr : excels)                    {                        if (!ArrayUtils.contains(this.excludeFields, field.getName() + "." + attr.targetAttr())                                && (attr != null && (attr.type() == Type.ALL || attr.type() == type)))                        {                            field.setAccessible(true);                            fields.add(new Object[] { field, attr });                        }                    }                }            }        }        return fields;    }    /**     * 根据注解获取最大行高     */    public short getRowHeight()    {        double maxHeight = 0;        for (Object[] os : this.fields)        {            Excel excel = (Excel) os[1];            maxHeight = Math.max(maxHeight, excel.height());        }        return (short) (maxHeight * 20);    }    /**     * 创建一个工作簿     */    public void createWorkbook()    {        this.wb = new SXSSFWorkbook(500);        this.sheet = wb.createSheet();        wb.setSheetName(0, sheetName);        this.styles = createStyles(wb);    }    /**     * 创建工作表     *      * @param sheetNo sheet数量     * @param index 序号     */    public void createSheet(int sheetNo, int index)    {        // 设置工作表的名称.        if (sheetNo > 1 && index > 0)        {            this.sheet = wb.createSheet();            this.createTitle();            wb.setSheetName(index, sheetName + index);        }    }    /**     * 获取单位格值     *      * @param row 获取的行     * @param column 获取单位格列号     * @return 单位格值     */    public Object getCellValue(Row row, int column)    {        if (row == null)        {            return row;        }        Object val = "";        try        {            Cell cell = row.getCell(column);            if (StringUtils.isNotNull(cell))            {                if (cell.getCellType() == CellType.NUMERIC || cell.getCellType() == CellType.FORMULA)                {                    val = cell.getNumericCellValue();                    if (DateUtil.isCellDateFormatted(cell))                    {                        val = DateUtil.getJavaDate((Double) val); // POI Excel 日期格式转换                    }                    else                    {                        if ((Double) val % 1 != 0)                        {                            val = new BigDecimal(val.toString());                        }                        else                        {                            val = new DecimalFormat("0").format(val);                        }                    }                }                else if (cell.getCellType() == CellType.STRING)                {                    val = cell.getStringCellValue();                }                else if (cell.getCellType() == CellType.BOOLEAN)                {                    val = cell.getBooleanCellValue();                }                else if (cell.getCellType() == CellType.ERROR)                {                    val = cell.getErrorCellValue();                }            }        }        catch (Exception e)        {            return val;        }        return val;    }    /**     * 判断是否是空行     *      * @param row 判断的行     * @return     */    private boolean isRowEmpty(Row row)    {        if (row == null)        {            return true;        }        for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++)        {            Cell cell = row.getCell(i);            if (cell != null && cell.getCellType() != CellType.BLANK)            {                return false;            }        }        return true;    }    /**     * 获取Excel2003图片     *     * @param sheet 当前sheet对象     * @param workbook 工作簿对象     * @return Map key:图片单位格索引(1_1)String,value:图片流PictureData     */    public static Map<String, PictureData> getSheetPictures03(HSSFSheet sheet, HSSFWorkbook workbook)    {        Map<String, PictureData> sheetIndexPicMap = new HashMap<String, PictureData>();        List<HSSFPictureData> pictures = workbook.getAllPictures();        if (!pictures.isEmpty())        {            for (HSSFShape shape : sheet.getDrawingPatriarch().getChildren())            {                HSSFClientAnchor anchor = (HSSFClientAnchor) shape.getAnchor();                if (shape instanceof HSSFPicture)                {                    HSSFPicture pic = (HSSFPicture) shape;                    int pictureIndex = pic.getPictureIndex() - 1;                    HSSFPictureData picData = pictures.get(pictureIndex);                    String picIndex = anchor.getRow1() + "_" + anchor.getCol1();                    sheetIndexPicMap.put(picIndex, picData);                }            }            return sheetIndexPicMap;        }        else        {            return sheetIndexPicMap;        }    }    /**     * 获取Excel2007图片     *     * @param sheet 当前sheet对象     * @param workbook 工作簿对象     * @return Map key:图片单位格索引(1_1)String,value:图片流PictureData     */    public static Map<String, PictureData> getSheetPictures07(XSSFSheet sheet, XSSFWorkbook workbook)    {        Map<String, PictureData> sheetIndexPicMap = new HashMap<String, PictureData>();        for (POIXMLDocumentPart dr : sheet.getRelations())        {            if (dr instanceof XSSFDrawing)            {                XSSFDrawing drawing = (XSSFDrawing) dr;                List<XSSFShape> shapes = drawing.getShapes();                for (XSSFShape shape : shapes)                {                    if (shape instanceof XSSFPicture)                    {                        XSSFPicture pic = (XSSFPicture) shape;                        XSSFClientAnchor anchor = pic.getPreferredSize();                        CTMarker ctMarker = anchor.getFrom();                        String picIndex = ctMarker.getRow() + "_" + ctMarker.getCol();                        sheetIndexPicMap.put(picIndex, pic.getPictureData());                    }                }            }        }        return sheetIndexPicMap;    }    /**     * 格式化不同范例的日期对象     *      * @param dateFormat 日期格式     * @param val 被格式化的日期对象     * @return 格式化后的日期字符     */    public String parseDateToStr(String dateFormat, Object val)    {        if (val == null)        {            return "";        }        String str;        if (val instanceof Date)        {            str = DateUtils.parseDateToStr(dateFormat, (Date) val);        }        else if (val instanceof LocalDateTime)        {            str = DateUtils.parseDateToStr(dateFormat, DateUtils.toDate((LocalDateTime) val));        }        else if (val instanceof LocalDate)        {            str = DateUtils.parseDateToStr(dateFormat, DateUtils.toDate((LocalDate) val));        }        else        {            str = val.toString();        }        return str;    }    /**     * 是否有对象的子列表     */    public boolean isSubList()    {        return StringUtils.isNotNull(subFields) && subFields.size() > 0;    }    /**     * 是否有对象的子列表,聚集不为空     */    public boolean isSubListValue(T vo)    {        return StringUtils.isNotNull(subFields) && subFields.size() > 0 && StringUtils.isNotNull(getListCellValue(vo)) && getListCellValue(vo).size() > 0;    }    /**     * 获取聚集的值     */    public Collection<?> getListCellValue(Object obj)    {        Object value;        try        {            value = subMethod.invoke(obj, new Object[] {});        }        catch (Exception e)        {            return new ArrayList<Object>();        }        return (Collection<?>) value;    }    /**     * 获取对象的子列表方法     *      * @param name 名称     * @param pojoClass 类对象     * @return 子列表方法     */    public Method getSubMethod(String name, Class<?> pojoClass)    {        StringBuffer getMethodName = new StringBuffer("get");        getMethodName.append(name.substring(0, 1).toUpperCase());        getMethodName.append(name.substring(1));        Method method = null;        try        {            method = pojoClass.getMethod(getMethodName.toString(), new Class[] {});        }        catch (Exception e)        {            log.error("获取对象非常{}", e.getMessage());        }        return method;    }}
复制代码


======================================================
参考自:
https://www.iteye.com/blog/357029540-2438298
下面工具类为该文下的POI处理表格数据的源码:
  1. package com.chinamobile.util;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.apache.poi.hssf.usermodel.HSSFWorkbook;
  4. import org.apache.poi.ss.usermodel.*;
  5. import org.apache.poi.ss.util.CellRangeAddress;
  6. import org.apache.poi.xssf.usermodel.XSSFWorkbook;
  7. import org.springframework.web.multipart.MultipartFile;
  8. import java.io.FileNotFoundException;
  9. import java.io.IOException;
  10. import java.io.InputStream;
  11. import java.text.SimpleDateFormat;
  12. import java.util.ArrayList;
  13. import java.util.List;
  14. import java.util.Optional;
  15. /**
  16. * @author liaoyubo
  17. * @version 1.0
  18. * @date 2019/2/27
  19. * @description
  20. */
  21. @Slf4j
  22. public class POIUtils {
  23.     private final static String XLS = "xls";
  24.     private final static String XLSX = "xlsx";
  25.     private static SimpleDateFormat sdf;
  26.     /**
  27.      * 读入excel文件,解析后返回
  28.      *
  29.      * @param file
  30.      * @throws IOException
  31.      */
  32.     public static List<String[]> readExcel(MultipartFile file) throws IOException {
  33.         //检查文件
  34.         checkFile(file);
  35.         //获得Workbook工作薄对象
  36.         Workbook workbook = getWorkBook(file);
  37.         //创建返回对象,把每行中的值作为一个数组,所有行作为一个集合返回
  38.         List<String[]> list = new ArrayList<>();
  39.         if (workbook != null) {
  40.             for (int sheetNum = 0; sheetNum < workbook.getNumberOfSheets(); sheetNum++) {
  41.                 //获得当前sheet工作表
  42.                 Sheet sheet = workbook.getSheetAt(sheetNum);
  43.                 if (sheet == null) {
  44.                     continue;
  45.                 }
  46.                 //获得当前sheet的开始行
  47.                 int firstRowNum = sheet.getFirstRowNum();
  48.                 //获得当前sheet的结束行
  49.                 int lastRowNum = sheet.getLastRowNum();
  50.                 //循环除了第一行的所有行
  51.                 list = rowList(sheet,firstRowNum + 1,lastRowNum);
  52.             }
  53.             workbook.close();
  54.         }
  55.         return list;
  56.     }
  57.     public static List<String[]> readExcel(MultipartFile file,
  58.                                            int sheetNum,
  59.                                            int startRow) throws IOException {
  60.         //检查文件
  61.         checkFile(file);
  62.         //获得Workbook工作薄对象
  63.         Workbook workbook = getWorkBook(file);
  64.         //创建返回对象,把每行中的值作为一个数组,所有行作为一个集合返回
  65.         List<String[]> list = new ArrayList<>();
  66.         if (workbook != null) {
  67.             //获得当前sheet工作表
  68.             Sheet sheet = workbook.getSheetAt(sheetNum);
  69.             if (!Optional.ofNullable(sheet).isPresent()) {
  70.                 return null;
  71.             }
  72.             //获得当前sheet的结束行
  73.             int lastRowNum = sheet.getLastRowNum();
  74.             //循环指定的所有行
  75.             list = rowList(sheet,startRow,lastRowNum);
  76.             workbook.close();
  77.         }
  78.         return list;
  79.     }
  80.     /**
  81.      * 检查文件是否正确
  82.      *
  83.      * @param file
  84.      * @throws IOException
  85.      */
  86.     private static void checkFile(MultipartFile file) throws IOException {
  87.         //判断文件是否存在
  88.         if (null == file) {
  89.             log.error("文件不存在!");
  90.             throw new FileNotFoundException("文件不存在!");
  91.         }
  92.         //获得文件名
  93.         String fileName = file.getOriginalFilename();
  94.         //判断文件是否是excel文件
  95.         if (!fileName.endsWith(XLS) && !fileName.endsWith(XLSX)) {
  96.             log.error(fileName + "不是excel文件");
  97.             throw new IOException(fileName + "不是excel文件");
  98.         }
  99.     }
  100.     /**
  101.      * 对文件解析
  102.      *
  103.      * @param file
  104.      * @return
  105.      */
  106.     private static Workbook getWorkBook(MultipartFile file) {
  107.         //获得文件名
  108.         String fileName = file.getOriginalFilename();
  109.         //创建Workbook工作薄对象,表示整个excel
  110.         Workbook workbook = null;
  111.         try {
  112.             //获取excel文件的io流
  113.             InputStream is = file.getInputStream();
  114.             //根据文件后缀名不同(xls和xlsx)获得不同的Workbook实现类对象
  115.             if (fileName.endsWith(XLS)) {
  116.                 //2003
  117.                 workbook = new HSSFWorkbook(is);
  118.             } else if (fileName.endsWith(XLSX)) {
  119.                 //2007
  120.                 workbook = new XSSFWorkbook(is);
  121.             }
  122.         } catch (IOException e) {
  123.             log.info(e.getMessage());
  124.         }
  125.         return workbook;
  126.     }
  127.     /**
  128.      * 判断是否是合并行
  129.      *
  130.      * @param sheet
  131.      * @param row
  132.      * @param column
  133.      * @return
  134.      */
  135.     private static boolean isMergedRow(Sheet sheet, int row, int column) {
  136.         int sheetMergeCount = sheet.getNumMergedRegions();
  137.         for (int i = 0; i < sheetMergeCount; i++) {
  138.             CellRangeAddress cellAddresses = sheet.getMergedRegion(i);
  139.             int firstColumn = cellAddresses.getFirstColumn();
  140.             int lastColumn = cellAddresses.getLastColumn();
  141.             int firstRow = cellAddresses.getFirstRow();
  142.             int lastRow = cellAddresses.getLastRow();
  143.             if (row >= firstRow && row <= lastRow) {
  144.                 if (column >= firstColumn && column <= lastColumn) {
  145.                     return true;
  146.                 }
  147.             }
  148.         }
  149.         return false;
  150.     }
  151.     /**
  152.      * 获取合并行的数据
  153.      *
  154.      * @param sheet
  155.      * @param row
  156.      * @param column
  157.      * @return
  158.      */
  159.     private static String getMergedRegionValue(Sheet sheet, int row, int column) {
  160.         // 获得该sheet所有合并单元格数量
  161.         int sheetMergeCount = sheet.getNumMergedRegions();
  162.         for (int i = 0; i < sheetMergeCount; i++) {
  163.             // 获得合并区域
  164.             CellRangeAddress cellAddresses = sheet.getMergedRegion(i);
  165.             int firstColumn = cellAddresses.getFirstColumn();
  166.             int lastColumn = cellAddresses.getLastColumn();
  167.             int firstRow = cellAddresses.getFirstRow();
  168.             int lastRow = cellAddresses.getLastRow();
  169.             /*判断传入的单元格的行号列号是否在合并单元格的范围内,
  170.             如果在合并单元格的范围内,择返回合并区域的首单元格格值
  171.              */
  172.             if (row >= firstRow && row <= lastRow) {
  173.                 if (column >= firstColumn && column <= lastColumn) {
  174.                     Row firRow = sheet.getRow(firstRow);
  175.                     Cell firCell = firRow.getCell(firstColumn);
  176.                     return getCellValue(firCell);
  177.                 }
  178.             }
  179.         }
  180.         // 如果该单元格行号列号不在任何一个合并区域,则返回null
  181.         return null;
  182.     }
  183.     /**
  184.      * 获取行的集合
  185.      * @param sheet
  186.      * @param startRow
  187.      * @param lastRowNum
  188.      * @return
  189.      */
  190.     private static List<String[]> rowList(Sheet sheet,int startRow,int lastRowNum){
  191.         List<String[]> list = new ArrayList<>();
  192.         for (int rowNum = startRow; rowNum <= lastRowNum; rowNum++) {
  193.             //获得当前行
  194.             Row row = sheet.getRow(rowNum);
  195.             if (!Optional.ofNullable(row).isPresent()) {
  196.                 continue;
  197.             }
  198.             //获得当前行的开始列
  199.             int firstColumn = row.getFirstCellNum();
  200.             //获得当前行的列数
  201.             int lastColumn = row.getPhysicalNumberOfCells();
  202.             String[] cells = new String[lastColumn];//行内所有列的值
  203.             //循环当前行的所有列
  204.             for (int column = firstColumn; column < lastColumn; column++) {
  205.                 Cell cell = row.getCell(column);//遍历中的某列
  206.                 // 判断是否合并行
  207.                 boolean isMerge = isMergedRow(sheet, rowNum, column);
  208.                 if (isMerge) {
  209.                     //是合并行,则获取合并行数据
  210.                     cells[column] = getMergedRegionValue(sheet, rowNum, column);
  211.                 } else {
  212.                     cells[column] = getCellValue(cell);//默认当前列内值
  213.                 }
  214.             }
  215.             list.add(cells);
  216.         }
  217.         return list;
  218.     }
  219.     /**
  220.      * 获取单元格值
  221.      *
  222.      * @param cell
  223.      * @return
  224.      */
  225.     private static String getCellValue(Cell cell) {
  226.         String cellValue = "";
  227.         if (cell == null) {
  228.             return cellValue;
  229.         }
  230.         // 把数字当成String来读,避免出现1读成1.0的情况
  231.         if (cell.getCellType() == CellType.NUMERIC) {
  232.             cell.setCellType(CellType.STRING);
  233.         }
  234.         // 判断数据的类型
  235.         switch (cell.getCellType()) {
  236.             // 文本
  237.             case STRING:
  238.                 cellValue = cell.getStringCellValue();
  239.                 break;
  240.             // 数字、日期
  241.             case NUMERIC:
  242.                 if (DateUtil.isCellDateFormatted(cell)) {
  243.                     sdf = new SimpleDateFormat("yyyy/MM/dd");
  244.                     // 日期型
  245.                     cellValue = sdf.format(cell.getDateCellValue());
  246.                 } else {
  247.                     // 数字
  248.                     cellValue = String.valueOf(cell.getNumericCellValue());
  249.                 }
  250.                 break;
  251.             // 布尔型
  252.             case BOOLEAN:
  253.                 cellValue = String.valueOf(cell.getBooleanCellValue());
  254.                 break;
  255.             // 空白
  256.             case BLANK:
  257.                 cellValue = cell.getStringCellValue();
  258.                 break;
  259.             // 错误
  260.             case ERROR:
  261.                 cellValue = "";
  262.                 break;
  263.             // 公式
  264.             case FORMULA:
  265.                 cellValue = "";
  266.                 break;
  267.             default:
  268.                 cellValue = "";
  269.         }
  270.         return cellValue;
  271.     }
  272. }
复制代码

==========================================
其他POI处理归并行的参考:(未验证是否可用)
https://www.cnblogs.com/zhou-pan/p/10037438.html













免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

吴旭华

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表