EasyExcel导出自定义下拉数据集的Excel模板文件

有时候因为业务需要,导出的Excel模板里面的单元格下拉数据集可能是用户在系统中自定义的数据字典数据,我们需要通过接口拿到相应字段的对应数据集,导出类似下方这种模板:

EasyExcel的api地址:常见api · 语雀

主要处理方式是如下:

  1. 使用自定义注解的方式,来标识Entity中哪个字段是需要使用下拉数据集的,这个下拉数据集的数据是固定的 比如性别:{"男","女"},还是说是从我们的数据库中通过接口动态获取的,比如某个数据字典的值
  2. 自定义拦截器,实现下拉数据集的操作 官方的demo中其实有许多的实例,我们可以参考进行扩展操作,关于自定义拦截器,官方给出的demo地址:https://github.com/alibaba/easyexcel/blob/master/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/CustomSheetWriteHandler.java

   自定义注解: 

/**
 * 标记导出excel的下拉数据集
 */
@Documented
// 作用在字段上
@Target(ElementType.FIELD)
// 运行时有效
@Retention(RetentionPolicy.RUNTIME)
public @interface DropDownSetField {
    // 固定下拉内容
    String[] source() default {};
    // 动态下拉内容
    Class[] sourceClass() default {};
}

 解析下拉数据集工具:

public class ResoveDropAnnotationUtil {


    public static String[] resove(DropDownSetField dropDownSetField){
        if(!Optional.ofNullable(dropDownSetField).isPresent()){
            return null;
        }

        // 获取固定下拉信息
        String[] source = dropDownSetField.source();
        if(null != source && source.length > 0){
            return source;
        }

        // 获取动态的下拉数据
        Class<? extends DropDownSetInterface>[] classes = dropDownSetField.sourceClass();
        if(null != classes && classes.length > 0){
            try {
                DropDownSetInterface dropDownSetInterface = Arrays.stream(classes).findFirst().get().newInstance();
                String[] dynamicSource = dropDownSetInterface.getSource();
                if(null != dynamicSource && dynamicSource.length > 0){
                    return dynamicSource;
                }
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

}

   Entity中标识下拉数据集字段: 

@Data
public class ProductModel {

    @ExcelProperty(value = "商品名称")
    private String name;

    @ExcelProperty(value = "商品类型")
    @DropDownSetField(source = {"固体","液体"})
    private String type;

    @ExcelProperty(value = "单位")
    @DropDownSetField(sourceClass = DropDownSetImpl.class)
    private String unit;

}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

动态下拉数据集接口实现类(Entity中的单位下拉数据集来自DropDownSetImpl.class) 

public interface DropDownSetInterface {

    String[] getSource();

}

public class DropDownSetImpl implements DropDownSetInterface {
    @Override
    public String[] getSource() {
        return new String[]{"g","kg","t","ml","l","米","千米"};
    }
}

 自定义拦截器处理:

public class ProductCellWriteHandler implements SheetWriteHandler {

    private Map<Integer,String[]> map = null;

    public ProductCellWriteHandler(Map<Integer,String[]> map){
        this.map = map;
    }

    @Override
    public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
    }

    @Override
    public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
        // 这里可以对cell进行任何操作
        Sheet sheet = writeSheetHolder.getSheet();
        DataValidationHelper helper = sheet.getDataValidationHelper();
        // k 为存在下拉数据集的单元格下表 v为下拉数据集
        map.forEach((k, v) -> {
            // 下拉列表约束数据
            DataValidationConstraint constraint = helper.createExplicitListConstraint(v);
            // 设置下拉单元格的首行 末行 首列 末列
            CellRangeAddressList rangeList = new CellRangeAddressList(1, 65536, k, k);
            // 设置约束
            DataValidation validation = helper.createValidation(constraint, rangeList);
            // 阻止输入非下拉选项的值
            validation.setErrorStyle(DataValidation.ErrorStyle.STOP);
            validation.setShowErrorBox(true);
            validation.setSuppressDropDownArrow(true);
            validation.createErrorBox("提示","此值与单元格定义格式不一致");
            // validation.createPromptBox("填写说明:","填写内容只能为下拉数据集中的单位,其他单位将会导致无法入仓");
            sheet.addValidationData(validation);
        });
    }
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

生成自定义模板代码:

    @Test
    public void export() throws IOException {
        File file = new File("D:/商品导入模板.xlsx");
        // 文件不存在即创建 存在即返回false
        file.createNewFile();
        FileOutputStream fileOutputStream = new FileOutputStream(file);
        // 获取改类声明的所有字段
        Field[] fields = ProductModel.class.getDeclaredFields();
        // 响应字段对应的下拉集合
        Map<Integer, String[]> map = new HashMap<>();
        Field field = null;
        // 循环判断哪些字段有下拉数据集,并获取
        for(int i =0;i<fields.length;i++){
            field = fields[i];
            // 解析注解信息
            DropDownSetField dropDownSetField = field.getAnnotation(DropDownSetField.class);
            if(null != dropDownSetField){
                String[] sources = ResoveDropAnnotationUtil.resove(dropDownSetField);
                if(null != sources && sources.length > 0){
                    map.put(i,sources);
                }
            }
        }
        ExcelWriter excelWriter = EasyExcel.write(fileOutputStream,ProductModel.class)
                .registerWriteHandler(new ProductCellWriteHandler(map)).build();
        WriteSheet sheet = EasyExcel.writerSheet(0,"商品模板").build();
        excelWriter.write(null,sheet);
        //sheet = EasyExcel.writerSheet(1,"单位说明").build();
        //excelWriter.write(null,sheet);
        excelWriter.finish();
    }
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

根据提供的引用内容,easyExcel虽然比poi更为简单api和更高性能,但是其下载格式不符合要求,需要进行个性化需求的设置。而easyExcel导出自定义图片格式,可以通过以下步骤实现: 1. 首先,需要在pom.xml文件中添加依赖: ```xml <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.2.10</version> </dependency> ``` 2. 然后,在需要导出的实体类中,添加一个byte[]类型的字段,用于存储图片的二进制数据。 ```java public class DemoData { private String name; private Integer age; private byte[] image; // 省略getter/setter方法 } ``` 3. 接着,在写入Excel时,将图片的二进制数据写入到对应的单元格中。 ```java // 构造数据 List<DemoData> list = new ArrayList<>(); DemoData data = new DemoData(); data.setName("张三"); data.setAge(20); // 读取图片文件 File file = new File("image.png"); byte[] imageBytes = FileUtils.readFileToByteArray(file); data.setImage(imageBytes); list.add(data); // 写入Excel String fileName = "demo.xlsx"; String sheetName = "Sheet1"; ExcelWriter excelWriter = EasyExcel.write(fileName).build(); WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).build(); excelWriter.write(list, writeSheet); excelWriter.finish(); ``` 4. 最后,在读取Excel时,将图片的二进制数据读取出来,并将其转换为图片格式。 ```java // 读取Excel String fileName = "demo.xlsx"; String sheetName = "Sheet1"; ExcelReader excelReader = EasyExcel.read(fileName).build(); ReadSheet readSheet = EasyExcel.readSheet(sheetName).build(); List<DemoData> list = excelReader.read(readSheet).head(DemoData.class).sheet().doReadSync(); // 将图片的二进制数据转换为图片格式 for (DemoData data : list) { byte[] imageBytes = data.getImage(); BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageBytes)); // 处理图片 // ... } excelReader.finish(); ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值