使用HuTool读取,写入,删除Excel,自定义Excel中的Sheet名称和列名,同类文件批量读取合并,批量删除

使用HuTool读取,写入,删除Excel,自定义Excel中的Sheet名称和列名

1 思路分析

1.1 读取文件

ExcelReader reader = ExcelUtil.getReader(file)//file为读取的目标文件
List<T> list = reader.readAll(clazz);//clazz的类型为class<T>

1.2 写入文件

//destFile为写入的目标文件,不存在则新建文件
//sheetName为写入的sheetName,不存在则新建sheet
ExcelWriter writer = ExcelWriter.getWriter(File destFile, String sheetName);
//list为写入的数据
writer.write(list);

1.3 删除文件

//file为删除的文件
FileUtil.del(file)

1.4 自定义别名

1.4.1 编写@ExcelAlias注解,值为该字段队形的excel中的列名

@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExcelAlias {
    String value()  default "";
}

1.4.2 每个需要自定义列名的字段都需要加对应的@ExcelAlias注解,如:

   @ExcelAlias("学号")
    public String stuNo;

1.4.3 在读取或者写入之前,获取字段上@ExcelAlias的值,并调用setHeaderAlias(headerAlias)方法批量设置字段的别名

	//headerAlias为Map集合
	//读取时为reader批量设置列名 每个键值对格式为:(“别名”, “字段名”), 从excel中读取到“已有的(别名)”, 改为“想改的(字段名)”
    reader.setHeaderAlias(headerAlias);
    //写入时为writer批量设置列名 每个键值对格式为:(“字段名”, “别名”), 每个字段对应的“已有的(字段名)”, 改为“想改的(别名)”
    writer.setHeaderAlias(headerAlias);

1.4.4 批量获取headerAlias的方法getHeaderAlias(Class clazz, boolean isRead)

 /**
     * 获得一个类所有 有别名的 字段 和 别名
     *
     * @param clazz  类
     * @param isRead 每个键值对格式为 ("已有的","想改的")
     *               true 读取时 每个键值对格式为:(“别名”, “字段名”), 从excel中读取到“已有的(别名)”, 改为“想改的(字段名)”
     *               false 写入时 每个键值对格式为:(“字段名”, “别名”), 每个字段对应的“已有的(字段名)”, 改为“想改的(别名)”
     * @param <T>
     * @return
     */
    private static <T> Map<String, String> getHeaderAlias(Class<T> clazz, boolean isRead) {
        Map headerAlias = new LinkedHashMap<String, String>();
        // Hutool 获取字段集合的方法,无需try/catch
        List<Field> fields = Arrays.asList(ReflectUtil.getFields(clazz));
        if (fields.isEmpty()) {
            return headerAlias;
        }
        for (Field field : fields) {
            // 获得每个字段的 @ExcelAlias注解
            ExcelAlias anno = field.getAnnotation(ExcelAlias.class);
            if (anno == null || "".equals(anno.value())) {
                continue;
            }
            if (isRead) {
                // 读取时 每个键值对格式为:(“别名”, “字段名”)
                headerAlias.put(anno.value(), field.getName());
            } else {
                // 写入时 每个键值对格式为:(“字段名”, “别名”)
                headerAlias.put(field.getName(), anno.value());
            }
        }
        return headerAlias;
    }

1.5 写入时自定义写入的Sheet名称

1.5.1 自定义@SheetName注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SheetName {

    String value() default SheetNameConstant.DEFAULT_NOTE_SHEET_NAME;

}

1.5.2 在类名上添加@SheetName注解,值为Sheet的名称

@Data
@SheetName("自定义Sheet名称")
public class Student {

1.5.3 获取@SheetName注解注解上的值,并构建对应的writer

//获得SheetName注解
SheetName anno = clazz.getAnnotation(SheetName.class);
//如果不需要自定义sheet名称,默认为sheet1
String sheetName = 
	(anno == null ? "sheet1" : anno.value());
//构建writer,path为写入的路径,sheetName为自定义的sheet名称
ExcelWriter writer = ExcelWriter.getWriter(new File(path), sheetName);

1.6 根据根目录和文件名前缀,获得根目录下所有符合条件的文件路径

  /**
     * 查找路径pathPre下,名字包含字段namePre的所有文件路径
     *
     * @param pathPre
     * @param namePre
     * @return
     */
    public static List<String> findAllNameByNamePre(String pathPre, String namePre) {
        List<String> list = new ArrayList<>();
        File folder = new File(pathPre);
        String[] names = folder.list();
        if (Objects.isNull(names) || names.length == 0) {
            return list;
        }
        for (String name : names) {
            if (name.startsWith(namePre)) {
                list.add(name);
            }
        }
        return list;
    }

1.7 获得根目录下更新时间最晚的文件

    /**
     * 获得修改时间最晚的
     * 该路径下包含该前缀的文件名称
     *
     * @param pathPre
     * @return
     */
    private String findNewestName(String pathPre, String namePre) {
        String name = "";
        File folder = new File(pathPre);
        long maxLastModified = 0l;
        File[] files = folder.listFiles();
        if (files == null) {
            return name;
        }
        for (File file : files) {
            if (file.getName().startsWith(namePre)) {
                maxLastModified = Math.max(file.lastModified(), maxLastModified);
                name = file.getName();
            }
        }
        return name;
    }

1.8 改进其自带writer写入时按列名的Hash排序顺序插入的问题

1.8.1 继承ExcelWriter

public class MyExcelWriter extends ExcelWriter {

1.8.2 重写write方法

 public ExcelWriter write(Iterable<?> data) {
        int index = 0;
        for (Object object : data) {
            if (object instanceof Iterable) {
                // 普通多行数据
                writeRow((Iterable<?>) object);
            } else if (object instanceof Map) {
                // Map表示一行,第一条数据的key做为标题行
                writeRows((Map<?, ?>) object, 0 == index);
            } else if (BeanUtil.isBean(object.getClass())) {
                // 一个Bean对象表示一行,ExcelWriter中使用的 BeanUtil.beanToMap(object) ,返回结果使用HashMap接收,导致写入excel时列的顺序按Hash值排序
                //this.writeRows(BeanUtil.beanToMap(object), 0 == index);
                // 使用自定义的beanToMap(),按照读取顺序排序,实现按字段顺序写入excel中的列
                writeRows(beanToMap(object), 0 == index);
            } else {
                break;
            }
            index++;
        }
        if (0 == index) {
            // 在无法识别元素类型的情况下,做为一行对待
            writeRow(data);
        }
        return this;
    }

1.8.3 自定义beanToMap(Object obj),使用LinkedHashMap接收,按插入顺序排序

    public Map<String, Object> beanToMap(Object obj) {
        Map map = new LinkedHashMap<String, String>();
        Class clazz = obj.getClass();
        //设置sheet名称
        SheetName anno = (SheetName) clazz.getAnnotation(SheetName.class);
        if (anno != null) {
            super.setOrCreateSheet(anno.value());
        }
        List<Field> fields = Arrays.asList(ReflectUtil.getFields(clazz));
        for (Field field : fields) {
            map.put(field.getName(), ReflectUtil.getFieldValue(obj, field));
        }
        return map;
    }

2 代码实现

2.1 注解包Anno

2.1.1 @SheetName注解类

package com.hsh.excelutil.Anno;

import com.hsh.excelutil.constant.SheetNameConstant;

import java.lang.annotation.*;

/**
 * @Author hsh
 * @DateTime 2023/09/05 17:15
 **/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SheetName {

    String value() default SheetNameConstant.DEFAULT_NOTE_SHEET_NAME;

}

2.1.2 @ExcelAlias注解类

package com.hsh.excelutil.Anno;

import java.lang.annotation.*;

/**
 * @Author hsh
 * @DateTime 2023/09/05 17:15
 **/
@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExcelAlias {

    String value()  default "";

}

2.2 常量包constant–SheetNameConstant常量类

package com.hsh.excelutil.constant;

/**
 * @Author hsh
 * @DateTime 2023/11/24 15:39
 **/
public class SheetNameConstant {
    public final static String DEFAULT_NOTE_SHEET_NAME = "sheet1";
}

2.3 实体类包poji–Student实体类

package com.hsh.excelutil.poji;

import com.hsh.excelutil.Anno.ExcelAlias;
import com.hsh.excelutil.Anno.SheetName;
import lombok.Data;

@Data
@SheetName("自定义Sheet名称")
public class Student {

    @ExcelAlias("学号")
    public String stuNo;

    @ExcelAlias("姓名")
    public String name;

    @ExcelAlias("性别")
    public String sex;

    @ExcelAlias("年龄")
    public String age;

    @ExcelAlias("班级")
    public String className;
}

2.4 工具包util

2.4.1 HuToolExcelUtil工具类,继承HuTool的ExcelUtil,可以使用HuTool的ExcelUtil的自带方法

package com.hsh.excelutil.util;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.hsh.excelutil.Anno.ExcelAlias;
import com.hsh.excelutil.Anno.SheetName;
import com.hsh.excelutil.constant.SheetNameConstant;

import java.io.File;
import java.lang.reflect.Field;
import java.util.*;

/**
 * @Author hsh
 * @DateTime 2023/09/09 14:56
 **/
public class HuToolExcelUtil extends ExcelUtil {

    /**
     * 读取Excel并转化为list
     * 需要指定返回时元素的类
     *
     * @param path  需要读取的Excel 的路径
     * @param clazz 指定的类,
     * @return list
     */
    public static <T> List<T> redaExcel(String path, Class<T> clazz) {
        File file = new File(path);
        List<T> list = new ArrayList<>();
        try (ExcelReader reader = ExcelUtil.getReader(file)) {
            reader.setHeaderAlias(getHeaderAlias(clazz, true));
            list = reader.readAll(clazz);
        }
        System.out.println("↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓\n读取文件:" + path + "\n内容");
        list.stream().forEach(v-> System.out.println());
        return list;
    }

    /**
     * 读取Excel并转化为list
     * 需要指定返回时元素的类
     *
     * @param names 需要读取的Excel 的集合
     * @param clazz 指定的类,
     * @return list
     */
    public static <T> List<T> redaExcels(String path, List<String> names, Class<T> clazz) {
        List<T> list = new ArrayList<>();
        for (String name : names) {
            list.addAll(redaExcel(path + name, clazz));
        }
        return list;
    }

    /**
     * 将list写入Excel中
     *
     * @param path 需要写入的Excel 的路径
     * @param list 写入的内容
     * @return
     */
    public static <T> void writeExcel(String path, List<T> list, Class<T> clazz) throws Exception {
        if (!path.endsWith(".xlsx") && !path.endsWith(".xls")) {
            path = path + ".xlsx";
        }
        Map headerAlias = getHeaderAlias(clazz, false);
        SheetName anno = clazz.getAnnotation(SheetName.class);
        try (MyExcelWriter writer = MyExcelWriter.getWriter(new File(path), anno == null ? SheetNameConstant.DEFAULT_NOTE_SHEET_NAME : anno.value())) {
            writer.setHeaderAlias(headerAlias);
            // 写入并刷盘
            writer.write(list);
            System.out.println("↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓\n写入文件:" + path + "\n内容");
            list.stream().forEach(v-> System.out.println());
        }

    }

    /**
     * 删除文件
     *
     * @param path
     * @return
     */
    public static int deleteExcel(String path) {
        File file = new File(path);
        if (FileUtil.del(file)) {
            System.out.println("↓↓↓↓↓↓↓↓↓↓\n删除文件:" + path);
            return 1;
        }
        return 0;
    }

    /**
     * 删除文件
     *
     * @param path
     * @return
     */
    public static int deleteExcels(String path, List<String> names) {
        int flag = 0;
        for (String name : names) {
            flag += deleteExcel(path + name);
        }
        return flag;
    }


    /**
     * 获得一个类所有 有别名的 字段 和 别名
     *
     * @param clazz  类
     * @param isRead 每个键值对格式为 ("已有的","想改的")
     *               true 读取时 每个键值对格式为:(“别名”, “字段名”), 从excel中读取到“已有的(别名)”, 改为“想改的(字段名)”
     *               false 写入时 每个键值对格式为:(“字段名”, “别名”), 每个字段对应的“已有的(字段名)”, 改为“想改的(别名)”
     * @param <T>
     * @return
     */
    private static <T> Map<String, String> getHeaderAlias(Class<T> clazz, boolean isRead) {
        Map headerAlias = new LinkedHashMap<String, String>();
        // Hutool 获取字段集合的方法,无需try/catch
        List<Field> fields = Arrays.asList(ReflectUtil.getFields(clazz));
        if (fields.isEmpty()) {
            return headerAlias;
        }
        for (Field field : fields) {
            // 获得每个字段的 @ExcelAlias注解
            ExcelAlias anno = field.getAnnotation(ExcelAlias.class);
            if (anno == null || "".equals(anno.value())) {
                continue;
            }
            if (isRead) {
                // 读取时 每个键值对格式为:(“别名”, “字段名”)
                headerAlias.put(anno.value(), field.getName());
            } else {
                // 写入时 每个键值对格式为:(“字段名”, “别名”)
                headerAlias.put(field.getName(), anno.value());
            }
        }
        return headerAlias;
    }

    /**
     * 查找路径pathPre下,名字包含字段namePre的所有文件路径
     *
     * @param pathPre
     * @param namePre
     * @return
     */
    public static List<String> findAllNameByNamePre(String pathPre, String namePre) {
        List<String> list = new ArrayList<>();
        File folder = new File(pathPre);
        String[] names = folder.list();
        if (Objects.isNull(names) || names.length == 0) {
            return list;
        }
        for (String name : names) {
            if (name.startsWith(namePre)) {
                list.add(name);
            }
        }
        return list;
    }
}

2.4.2 自定义MyExcelWriter,继承HuTool的ExcelWriter,改进其自带writer写入时按列名的Hash排序顺序插入的问题

package com.hsh.excelutil.util;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.poi.PoiChecker;
import cn.hutool.poi.excel.ExcelWriter;
import com.hsh.excelutil.Anno.SheetName;
import lombok.NoArgsConstructor;

import java.io.File;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author hsh
 * @DateTime 2023/11/23 13:53
 **/
@NoArgsConstructor
public class MyExcelWriter extends ExcelWriter {


    /**
     * 写出数据,本方法只是将数据写入Workbook中的Sheet,并不写出到文件<br>
     * 写出的起始行为当前行号,可使用{@link #getCurrentRow()}方法调用,根据写出的的行数,当前行号自动增加<br>
     * 样式为默认样式,可使用{@link #getCellStyle()}方法调用后自定义默认样式<br>
     * data中元素支持的类型有:
     *
     * <p>
     * 1. Iterable,既元素为一个集合,元素被当作一行,data表示多行<br>
     * 2. Map,既元素为一个Map,第一个Map的keys作为首行,剩下的行为Map的values,data表示多行 <br>
     * 3. Bean,既元素为一个Bean,第一个Bean的字段名列表会作为首行,剩下的行为Bean的字段值列表,data表示多行 <br>
     * 4. 无法识别,不输出
     * </p>
     *
     * @param data 数据
     * @return this
     */
    public ExcelWriter write(Iterable<?> data) {
        int index = 0;
        for (Object object : data) {
            if (object instanceof Iterable) {
                // 普通多行数据
                writeRow((Iterable<?>) object);
            } else if (object instanceof Map) {
                // Map表示一行,第一条数据的key做为标题行
                writeRows((Map<?, ?>) object, 0 == index);
            } else if (BeanUtil.isBean(object.getClass())) {
                // 一个Bean对象表示一行,ExcelWriter中使用的 BeanUtil.beanToMap(object) ,返回结果使用HashMap接收,导致写入excel时列的顺序按Hash值排序
                //this.writeRows(BeanUtil.beanToMap(object), 0 == index);
                // 使用自定义的beanToMap(),按照读取顺序排序,实现按字段顺序写入excel中的列
                writeRows(beanToMap(object), 0 == index);
            } else {
                break;
            }
            index++;
        }
        if (0 == index) {
            // 在无法识别元素类型的情况下,做为一行对待
            writeRow(data);
        }
        return this;
    }

    /**
     * 自定义beanToMap(),实现按字段顺序写入excel中的列
     * @param obj
     * @return 使用LinkedHashMap,按照读取顺序排序
     */
    public Map<String, Object> beanToMap(Object obj) {
        Map map = new LinkedHashMap<String, String>();
        Class clazz = obj.getClass();
        //设置sheet名称
        SheetName anno = (SheetName) clazz.getAnnotation(SheetName.class);
        if (anno != null) {
            super.setOrCreateSheet(anno.value());
        }
        List<Field> fields = Arrays.asList(ReflectUtil.getFields(clazz));
        for (Field field : fields) {
            map.put(field.getName(), ReflectUtil.getFieldValue(obj, field));
        }
        return map;
    }

    /**
     * 获得{@link ExcelWriter},默认写出到第一个sheet<br>
     * 不传入写出的Excel文件路径,只能调用{@link ExcelWriter#flush(OutputStream)}方法写出到流<br>
     * 若写出到文件,还需调用{@link ExcelWriter#setDestFile(File)}方法自定义写出的文件,然后调用{@link ExcelWriter#flush()}方法写出到文件
     *
     * @return {@link ExcelWriter}
     * @since 3.2.1
     */
    public static MyExcelWriter getWriter() {
        try {
            return new MyExcelWriter();
        } catch (NoClassDefFoundError e) {
            throw PoiChecker.transError(e);
        }
    }

    /**
     * 获得{@link ExcelWriter}
     *
     * @param destFile  目标文件
     * @param sheetName sheet表名
     * @return {@link ExcelWriter}
     */
    public static MyExcelWriter getWriter(File destFile, String sheetName) {
        try {
            return new MyExcelWriter(destFile, sheetName);
        } catch (NoClassDefFoundError e) {
            throw PoiChecker.transError(e);
        }
    }

    public MyExcelWriter(File destFile, String sheetName) {
        super(destFile, sheetName);
    }
}

3 效果测试

3.1 准备文件

文件准备

3.2编写测试类

package com.hsh.excelutil.util;

import com.hsh.excelutil.poji.Student;

import java.util.List;

public class HuToolExcelUtilTest {
    List<Student> students;
    List<String> names;

    @org.junit.Test
    public void redaExcel() {
        students = HuToolExcelUtil.redaExcel("d:\\Users\\USER\\Desktop\\java\\javaTest\\学生资料1班.xlsx", Student.class);
    }

    @org.junit.Test
    public void redaExcels() {
        names = HuToolExcelUtil.findAllNameByNamePre("d:\\Users\\USER\\Desktop\\java\\javaTest\\", "学生资料");

        students = HuToolExcelUtil.redaExcels("d:\\Users\\USER\\Desktop\\java\\javaTest\\", names, Student.class);
    }

    @org.junit.Test
    public void writeExcel() {
        redaExcels();
        try {
            HuToolExcelUtil.writeExcel("d:\\Users\\USER\\Desktop\\java\\javaTest\\学生资料.xlsx", students, Student.class);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    @org.junit.Test
    public void deleteExcel() {
        HuToolExcelUtil.deleteExcel("d:\\Users\\USER\\Desktop\\java\\javaTest\\学生资料.xlsx");

    }

    @org.junit.Test
    public void deleteExcels() {
        names = HuToolExcelUtil.findAllNameByNamePre("d:\\Users\\USER\\Desktop\\java\\javaTest\\", "学生资料");
        HuToolExcelUtil.deleteExcels("d:\\Users\\USER\\Desktop\\java\\javaTest\\", names);
    }


}

3.3 读取单个文件HuToolExcelUtilTest.redaExcel():学生资料1班

读取单个文件

3.4 批量读取文件HuToolExcelUtilTest.redaExcels():前缀为“学生资料”的

批量读取文件

3.5 写入文件HuToolExcelUtilTest.writeExcel()

写入文件1
写入文件2

3.6 删除指定文件HuToolExcelUtilTest.deleteExcel():学生资料1班

指定删除1

指定删除1

3.7 批量删除文件HuToolExcelUtilTest.deleteExcels():前缀为“学生资料”的

批量删除

批量删除2

  • 18
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用HutoolExcel进行操作非常方便,可以按照以下步骤实现: 1. 导入HutoolExcel依赖,例如: ```xml <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.7.10</version> </dependency> ``` 2. 读取Excel文件,例如: ```java // 加载Excel文件 ExcelReader reader = ExcelUtil.getReader("path/to/excel.xlsx"); // 获取Sheet ExcelSheet sheet = reader.getSheet(0); // 遍历行 for (int i = sheet.getFirstDataRowIndex(); i <= sheet.getLastDataRowIndex(); i++) { ExcelRow row = sheet.getRow(i); // 读取单元格数据 String cellValue = row.getCell(0).getRawValue(); // TODO: 处理数据 } // 关闭资源 reader.close(); ``` 3. 写入数据到新的Excel文件,例如: ```java // 创建Excel工作簿 ExcelWriter writer = ExcelUtil.getWriter("path/to/new.xlsx"); // 添加Sheet写入数据 writer.addSheet("Sheet1"); writer.writeHeadRow(Arrays.asList("标题1", "标题2", "标题3")); writer.writeRow(Arrays.asList("数据1", "数据2", "数据3"), true); // 关闭资源 writer.close(); ``` 4. 完整代码示例: ```java import cn.hutool.poi.excel.ExcelReader; import cn.hutool.poi.excel.ExcelUtil; import cn.hutool.poi.excel.ExcelWriter; import cn.hutool.poi.excel.sax.handler.RowHandler; import cn.hutool.poi.excel.sax.handler.SheetHandler; import cn.hutool.poi.excel.sax.handler.StyleHandler; import cn.hutool.poi.excel.sax.handler.WorkbookHandler; import cn.hutool.poi.excel.sax.handler.XlsxRowHandler; import cn.hutool.poi.excel.sax.handler.XlsxSheetHandler; import cn.hutool.poi.excel.sax.handler.XlsxStyleHandler; import cn.hutool.poi.excel.sax.handler.XlsxWorkbookHandler; import java.util.Arrays; public class ExcelDemo { public static void main(String[] args) { // 读取Excel文件 ExcelReader reader = ExcelUtil.getReader("path/to/excel.xlsx"); // 获取Sheet ExcelSheet sheet = reader.getSheet(0); // 遍历行 for (int i = sheet.getFirstDataRowIndex(); i <= sheet.getLastDataRowIndex(); i++) { ExcelRow row = sheet.getRow(i); // 读取单元格数据 String cellValue = row.getCell(0).getRawValue(); // TODO: 处理数据 } // 关闭资源 reader.close(); // 创建Excel工作簿 ExcelWriter writer = ExcelUtil.getWriter("path/to/new.xlsx"); // 添加Sheet写入数据 writer.addSheet("Sheet1"); writer.writeHeadRow(Arrays.asList("标题1", "标题2", "标题3")); writer.writeRow(Arrays.asList("数据1", "数据2", "数据3"), true); // 关闭资源 writer.close(); } } ``` 注意:读取Excel文件时,需要根据文件类型选择适当的`ExcelReader`,例如: - 如果是.xls文件,使用`ExcelReader reader = ExcelUtil.getReader("path/to/excel.xls");` - 如果是.xlsx文件,使用`ExcelReader reader = ExcelUtil.getBigReader("path/to/excel.xlsx");`

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值