java poi 生成 Xlsx格式的Excel工具类

目的

应对Excel生成的不同需求,使用一套Excel生成工具,避免重复造轮子。

工具类的功能

1、生成Xlsx格式的Excel文件
2、解的Xlsx格式的Excel文件
3、合并多个Xlsx格式的Excel文件

功能逻辑

设计思路:
1、先将数据集合转换为ExcelSheet 对象
2、再将ExcelSheet 对象生成Excel的字节流对象

类图如下:
在这里插入图片描述
类具有的功能:
AbstractGenerateExcelSheet 抽象类
1、将数据集合生成ExcelSheet对象(generateSheet方法)
2、ExcelSheet 对象转换(convertExcelSheet方法),将其他 ExcelSheet 转换为自己需要的 ExcelSheet

AbstractExportXlsxExcel 抽象类
1、将ExcelSheet 对象生成Xlsx格式的Excel文件字节流(exportExcel方法)
2、将多个Xlsx格式的Excel文件合并为一个ExcelSheet对象(mergeFirstSheetExcel方法)
3、生成Excel文件的特殊逻辑(addHook方法+hook方法)

代码实现

maven依赖:

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

注解类ExcelCellType
用途:用于标记单元格的数据类型

/**
 * @author huijing xu
 * @date 2020/8/24
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelCellType {
    enum Type {
        NUMBER_DOUBLE,
        NUMBER_INTEGER,
        STRING
    }

    Type cellTyp() default Type.STRING;
}

实体类ExcelSheet
用途:承载Excel单元格的数据,并根据此对象,生成Excel


/**
 * @author huijing xu
 * @date 2020/8/24
 */
public class ExcelSheet {
    // Excel中Sheet的name
    private String sheetName;
    // 标题行
    private LinkedList<String> rowNameList;
    // 数据行
    private List<Map<String, CellEntity>> rowValueList;

    public String getSheetName() {
        return sheetName;
    }

    public void setSheetName(String sheetName) {
        this.sheetName = sheetName;
    }

    public LinkedList<String> getRowNameList() {
        return rowNameList;
    }

    public void setRowNameList(LinkedList<String> rowNameList) {
        this.rowNameList = rowNameList;
    }

    public List<Map<String, CellEntity>> getRowValueList() {
        return rowValueList;
    }

    public void setRowValueList(List<Map<String, CellEntity>> rowValueList) {
        this.rowValueList = rowValueList;
    }

    // Excel中单元格对象
    public class CellEntity {
        // 单元格的值
        private Object cellValue;
        // 单元格的类型
        private ExcelCellType.Type type;

        public Object getCellValue() {
            return cellValue;
        }

        public void setCellValue(Object cellValue) {
            this.cellValue = cellValue;
        }

        public ExcelCellType.Type getType() {
            return type;
        }

        public void setType(ExcelCellType.Type type) {
            this.type = type;
        }
    }

}

生成Excel的抽象类
用途:生成Excel,解析Excel

/**
 * @author huijing xu
 * @date 2020/8/24
 */
@Slf4j
public abstract class AbstractExportXlsxExcel {

    protected Map<ExcelCellType.Type, XSSFCellStyle> cellStyleMap;

    /**
     * 将ExcelSheet,生成Xlsx格式的Excel文件字节流
     *
     * @param excelSheet
     * @return
     */
    public ByteArrayInputStream exportExcel(ExcelSheet excelSheet) {
        if (excelSheet == null) {
            return null;
        }
        return exportExcel(Arrays.asList(excelSheet));
    }


    /**
     * 将多个ExcelSheet,生成对应多个Sheet的Xlsx格式的Excel文件字节流
     *
     * @param sheetList
     * @return
     */
    public ByteArrayInputStream exportExcel(List<ExcelSheet> sheetList) {
        if (CollectionUtils.isEmpty(sheetList)) {
            return null;
        }

        try {
            XSSFWorkbook workbook = new XSSFWorkbook();

            generateCellStyle(workbook);

            for (ExcelSheet excelSheet : sheetList) {
                createSheet(workbook, excelSheet);
            }

            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            workbook.write(byteArrayOutputStream);
            ByteArrayInputStream inputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
            return inputStream;
        } catch (Exception e) {
            log.error("export excel of xlsx error:{}", e);
            throw new DataOperateException(e);
        }
    }

    /**
     * 将多个Xlsx格式的Excel文件合并为一个ExcelSheet对象
     * 合并后的标题取自第一个文件
     * 合并后的单元格对象,不具有单元格格式
     *
     * @param byteList
     * @return
     */
    public ExcelSheet mergeFirstSheetExcel(List<byte[]> byteList) {
        ExcelSheet excelSheet = new ExcelSheet();
        if (CollectionUtils.isEmpty(byteList)) {
            return excelSheet;
        }

        LinkedList<String> titleList = new LinkedList<>();
        List<Map<String, ExcelSheet.CellEntity>> excelSheetList = new ArrayList<>();

        for (int i = 0; i < byteList.size(); i++) {
            byte[] bytes = byteList.get(i);

            // 第一个文件
            if (i == 0) {
                titleList = parseTitle(bytes);
            }

            List<Map<String, ExcelSheet.CellEntity>> excelSheetMap = parseContent(bytes, titleList);
            excelSheetList.addAll(excelSheetMap);
        }

        excelSheet.setRowNameList(titleList);
        excelSheet.setRowValueList(excelSheetList);

        return excelSheet;
    }

    /**
     * 根据标题列表,解析文件的内容
     * 从第二行开始,默认第一行为标题行
     *
     * @param bytes
     * @param titleList
     * @return
     */
    private List<Map<String, ExcelSheet.CellEntity>> parseContent(byte[] bytes, LinkedList<String> titleList) {
        List<Map<String, ExcelSheet.CellEntity>> rowValueList = new ArrayList<>();
        if (bytes == null || bytes.length == 0 || CollectionUtils.isEmpty(titleList)) {
            return rowValueList;
        }
        try {
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
            XSSFWorkbook workbook = new XSSFWorkbook(byteArrayInputStream);

            // 获取第一个sheet
            XSSFSheet sheet = workbook.getSheetAt(0);

            // 获取此文件title映射的位置
            HashMap<String, Integer> titleIndexMap = generateTitleIndexMap(sheet);

            // 这个sheet最大的行
            int rowMax = sheet.getLastRowNum() + 1;
            // 内容行,从第二行开始
            for (int i = 1; i < rowMax; i++) {
                Row row = sheet.getRow(i);

                Map<String, ExcelSheet.CellEntity> cellEntityMap = new HashMap<>();
                for (String title : titleList) {
                    ExcelSheet.CellEntity cellEntity = generateCellEntity(title, titleIndexMap, row);
                    cellEntityMap.put(title, cellEntity);
                }

                rowValueList.add(cellEntityMap);
            }

            return rowValueList;
        } catch (Exception e) {
            log.error("parse Byte xlsx error:{}", e);
            throw new DataOperateException(e);
        }
    }

    /**
     * 根据标题,设置对应此标题的文本内容映射到第几列
     *
     * @param sheet
     * @return
     */
    private HashMap<String, Integer> generateTitleIndexMap(XSSFSheet sheet) {
        HashMap<String, Integer> titleIndexMap = new HashMap<>();
        Row titleRow = sheet.getRow(0);
        short titleRowSize = titleRow.getLastCellNum();
        for (int j = 0; j < titleRowSize; j++) {
            Cell cell = titleRow.getCell(j);
            if (cell != null) {
                String title = cell.getStringCellValue();
                titleIndexMap.put(title, j);
            }
        }
        return titleIndexMap;
    }

    private ExcelSheet.CellEntity generateCellEntity(String title, HashMap<String, Integer> titleIndexMap, Row row) {
        ExcelSheet.CellEntity cellEntity = null;

        Integer integer = titleIndexMap.get(title);
        if (integer != null) {
            Cell cell = row.getCell(integer);
            if (cell != null) {
                cellEntity = new ExcelSheet().new CellEntity();

                CellType cellType = cell.getCellType();
                switch (cellType) {
                    case NUMERIC:
                        cellEntity.setCellValue(cell.getNumericCellValue());
                        break;
                    case STRING:
                        cellEntity.setCellValue(cell.getStringCellValue());
                        break;
                    case BOOLEAN:
                        cellEntity.setCellValue(cell.getBooleanCellValue());
                        break;
                    case FORMULA:
                        cellEntity.setCellValue(cell.getCellFormula());
                        break;
                }
            }
        }

        return cellEntity;
    }

    /**
     * 解析出excel的title,以第一个文件的title为准
     *
     * @return
     */
    private LinkedList<String> parseTitle(byte[] bytes) {
        try {
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
            XSSFWorkbook workbook = new XSSFWorkbook(byteArrayInputStream);

            // 获取第一个sheet
            XSSFSheet sheet = workbook.getSheetAt(0);

            LinkedList<String> titleNameList = new LinkedList<>();

            Row titleRow = sheet.getRow(0);
            short titleRowSize = titleRow.getLastCellNum();
            for (int j = 0; j < titleRowSize; j++) {
                Cell cell = titleRow.getCell(j);
                if (cell != null) {
                    String title = cell.getStringCellValue();
                    titleNameList.add(title);
                }
            }

            return titleNameList;
        } catch (Exception e) {
            log.error("parse Byte xlsx error:{}", e);
            throw new DataOperateException(e);
        }
    }

    /**
     * 创建sheet
     *
     * @param workbook
     * @param excelSheet
     */
    private void createSheet(XSSFWorkbook workbook, ExcelSheet excelSheet) {
        XSSFSheet xssfSheet;
        if (StringUtils.isNotEmpty(excelSheet.getSheetName())) {
            xssfSheet = workbook.createSheet(excelSheet.getSheetName());
        } else {
            xssfSheet = workbook.createSheet();
        }

        createHeadRow(xssfSheet, excelSheet);

        createContentRow(xssfSheet, excelSheet);
    }

    /**
     * 创建表头行
     *
     * @param xssfSheet
     * @param excelSheet
     */
    private void createHeadRow(XSSFSheet xssfSheet, ExcelSheet excelSheet) {
        XSSFRow headRow = xssfSheet.createRow(0);
        int columnIndex = 0;

        for (String title : excelSheet.getRowNameList()) {
            XSSFCell headCell = headRow.createCell(columnIndex++);
            headCell.setCellStyle(cellStyleMap.get(ExcelCellType.Type.STRING));
            headCell.setCellValue(title);
        }
    }


    /**
     * 创建内容行
     *
     * @param xssfSheet
     * @param excelSheet
     */
    private void createContentRow(XSSFSheet xssfSheet, ExcelSheet excelSheet) {
        // 文本行开始位置,从第二行开始
        int index = 1;
        List<Map<String, ExcelSheet.CellEntity>> rowValueList = excelSheet.getRowValueList();
        if (CollectionUtils.isEmpty(rowValueList)) {
            return;
        }

        LinkedList<String> rowNameList = excelSheet.getRowNameList();
        for (Map<String, ExcelSheet.CellEntity> row : rowValueList) {
            XSSFRow textRow = xssfSheet.createRow(index++);
            int j = 0;
            for (String title : rowNameList) {
                Object cellValue = null;
                ExcelCellType.Type cellType = null;

                ExcelSheet.CellEntity cellEntity = row.get(title);
                if (cellEntity != null) {
                    cellValue = row.get(title).getCellValue();
                    cellType = row.get(title).getType();
                }

                XSSFCell cell = textRow.createCell(j++);

                setContentCellValue(cell, cellValue, cellType);
            }
        }

        if (addHook(excelSheet)) {
            hook(index, xssfSheet, excelSheet);
        }
    }

    /**
     * 是否增加钩子方法,增加特殊逻辑
     *
     * @return
     */
    protected abstract boolean addHook(ExcelSheet excelSheet);


    /**
     * 钩子方法,实现特殊逻辑
     *
     * @param startRow
     * @param xssfSheet
     * @param excelSheet
     */
    protected abstract void hook(int startRow, XSSFSheet xssfSheet, ExcelSheet excelSheet);

    /**
     * 设置单元格格式以及单元格的内容
     *
     * @param cell
     * @param cellValue
     * @param cellType
     */
    private void setContentCellValue(XSSFCell cell, Object cellValue, ExcelCellType.Type cellType) {
        if (cellValue != null && cellType != null) {
            switch (cellType) {
                case NUMBER_DOUBLE:
                    XSSFCellStyle number = cellStyleMap.get(ExcelCellType.Type.NUMBER_DOUBLE);
                    cell.setCellStyle(number);
                    cell.setCellValue(cellValue != null ? Double.parseDouble(cellValue.toString()) : 0);
                    break;
                case NUMBER_INTEGER:
                    XSSFCellStyle integer = cellStyleMap.get(ExcelCellType.Type.NUMBER_INTEGER);
                    cell.setCellStyle(integer);
                    cell.setCellValue(cellValue != null ? Double.parseDouble(cellValue.toString()) : 0);
                    break;
                case STRING:
                    XSSFCellStyle stringStyle = cellStyleMap.get(ExcelCellType.Type.STRING);
                    cell.setCellStyle(stringStyle);
                    cell.setCellValue(cellValue != null ? cellValue.toString() : "");
            }
        }
    }

    /**
     * 生成cell的格式
     *
     * @param workbook
     */
    private void generateCellStyle(XSSFWorkbook workbook) {
        cellStyleMap = new HashMap<>();

        XSSFCellStyle numberStyle = generateNumberStyle(workbook);
        cellStyleMap.put(ExcelCellType.Type.NUMBER_DOUBLE, numberStyle);

        XSSFCellStyle integerStyle = generateIntegerStyle(workbook);
        cellStyleMap.put(ExcelCellType.Type.NUMBER_INTEGER, integerStyle);

        XSSFCellStyle stringStyle = generateStringStyle(workbook);
        cellStyleMap.put(ExcelCellType.Type.STRING, stringStyle);
    }

    /**
     * 统一的具有小数点精度(两位)数字类型cell格式
     *
     * @param workbook
     * @return
     */
    private XSSFCellStyle generateNumberStyle(XSSFWorkbook workbook) {
        XSSFCellStyle cellStyle = workbook.createCellStyle();

        XSSFDataFormat df = workbook.createDataFormat();
        // 保留两位小数点
        short format = df.getFormat("#,##0.00");
        cellStyle.setDataFormat(format);

        XSSFFont font = workbook.createFont();
        font.setFontName("Calibri");
        cellStyle.setFont(font);

        return cellStyle;
    }

    /**
     * 统一的不具有小数点精度数字类型cell格式
     *
     * @param workbook
     * @return
     */
    private XSSFCellStyle generateIntegerStyle(XSSFWorkbook workbook) {
        XSSFCellStyle cellStyle = workbook.createCellStyle();

        XSSFDataFormat df = workbook.createDataFormat();
        // 数字类型,不保留小数
        short format = df.getFormat("#,#0");
        cellStyle.setDataFormat(format);

        XSSFFont font = workbook.createFont();
        font.setFontName("Calibri");
        cellStyle.setFont(font);

        return cellStyle;
    }

    /**
     * 统一的字符串类型cell格式
     *
     * @param workbook
     * @return
     */
    private XSSFCellStyle generateStringStyle(XSSFWorkbook workbook) {
        XSSFCellStyle cellStyle = workbook.createCellStyle();

        XSSFFont font = workbook.createFont();
        font.setFontName("Calibri");
        cellStyle.setFont(font);

        return cellStyle;
    }

}

生成ExcelSheet对象的抽象类
用途:将数据集转为ExcelSheet对象,用于Excel的生成


/**
 * @author huijing xu
 * @date 2020/8/24
 */
public abstract class AbstractGenerateExcelSheet<T> {

    private LinkedHashMap<String, Field> fieldNameMap = new LinkedHashMap<>();
    private Map<String, ExcelCellType.Type> fieldCellTypeMap = new HashMap<>();

    @PostConstruct
    public void init() {
        Field[] fields = initFieldList();

        for (int i = 0; i < fields.length; i++) {
            Column column = fields[i].getAnnotation(Column.class);
            if (column != null) {
                fields[i].setAccessible(true);
                fieldNameMap.put(column.name(), fields[i]);

                ExcelCellType type = fields[i].getAnnotation(ExcelCellType.class);
                if (type != null) {
                    fieldCellTypeMap.put(column.name(), type.cellTyp());
                }
            }
        }
    }

    abstract Field[] initFieldList();

    /**
     * 根据数据集,生成ExcelSheet对象
     *
     * @param data
     * @param <T>
     * @return
     */
    public <T> ExcelSheet generateSheet(List<T> data) {
        return generateSheet(data, null);
    }

    public <T> ExcelSheet generateSheet(List<T> data, String sheetName) {
        ExcelSheet excelSheet = new ExcelSheet();
        excelSheet.setSheetName(sheetName);

        LinkedList<String> rowNameList = generateRowNameList();
        excelSheet.setRowNameList(rowNameList);

        List<Map<String, ExcelSheet.CellEntity>> rowValueList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(data)) {
            rowValueList = generateRowValueList(rowNameList, data);
        }
        excelSheet.setRowValueList(rowValueList);

        return excelSheet;
    }

    public ExcelSheet convertExcelSheet(ExcelSheet otherSheet) {
        return convertExcelSheet(otherSheet, null);
    }

    /**
     * 将其他 ExcelSheet 转换为自己需要的 ExcelSheet
     *
     * @param otherSheet 需要转换的ExcelSheet
     * @param sheetName  sheet的名称
     * @return
     */
    public ExcelSheet convertExcelSheet(ExcelSheet otherSheet, String sheetName) {
        ExcelSheet excelSheet = new ExcelSheet();
        excelSheet.setSheetName(sheetName);

        LinkedList<String> rowNameList = generateRowNameList();
        excelSheet.setRowNameList(rowNameList);

        List<Map<String, ExcelSheet.CellEntity>> rowValueList = new ArrayList<>();
        if (otherSheet != null && CollectionUtils.isNotEmpty(otherSheet.getRowValueList())) {
            otherSheet.getRowValueList().stream().forEach(v -> {
                Map<String, ExcelSheet.CellEntity> cellEntityMap = new HashMap<>();
                for (String fieldName : rowNameList) {
                    ExcelSheet.CellEntity cellEntity = v.get(fieldName);

                    if (cellEntity != null && cellEntity.getCellValue() != null) {
                        ExcelCellType.Type type = fieldCellTypeMap.get(fieldName);
                        cellEntity.setType(type);
                    }

                    cellEntityMap.put(fieldName, cellEntity);
                }
                rowValueList.add(cellEntityMap);
            });
        }
        excelSheet.setRowValueList(rowValueList);

        return excelSheet;
    }

    /**
     * 生成excel各列的名称
     *
     * @return
     */
    private LinkedList<String> generateRowNameList() {
        LinkedList<String> rowNameList = new LinkedList<>();
        if (MapUtils.isNotEmpty(fieldNameMap)) {
            for (String fieldName : fieldNameMap.keySet()) {
                rowNameList.add(fieldName);
            }
        }
        return rowNameList;
    }


    /**
     * 根据列名以及数据集,生成行数据 List<Map<String, ExcelSheet.CellEntity>>
     * 每行中列数据 Map<String, ExcelSheet.CellEntity> ,key为列名,value为ExcelSheet.CellEntity对象
     *
     * @param rowNameList
     * @param data
     * @param <T>
     * @return
     */
    private <T> List<Map<String, ExcelSheet.CellEntity>> generateRowValueList(LinkedList<String> rowNameList,
                                                                              List<T> data) {
        List<Map<String, ExcelSheet.CellEntity>> rowValueList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(data)) {
            for (T t : data) {
                Map<String, ExcelSheet.CellEntity> cellEntityMap = new HashMap<>();
                for (String rowName : rowNameList) {
                    ExcelSheet.CellEntity cellEntity = new ExcelSheet().new CellEntity();

                    Field field = fieldNameMap.get(rowName);
                    ExcelCellType.Type type = fieldCellTypeMap.get(rowName);
                    try {
                        cellEntity.setCellValue(field.get(t));
                        cellEntity.setType(type);

                        cellEntityMap.put(rowName, cellEntity);
                    } catch (IllegalAccessException e) {
                        throw new DataOperateException(e);
                    }
                    cellEntityMap.put(rowName, cellEntity);
                }
                rowValueList.add(cellEntityMap);
            }
        }
        return rowValueList;
    }

}

具体使用

1、实现 AbstractExportXlsxExcel 抽象类

/**
 * @author huijing xu
 * @date 2020/8/25
 */
@Component
public class NormalExportXlsxExcel extends AbstractExportXlsxExcel {

    @Override
    protected boolean addHook(ExcelSheet excelSheet) {
        return false;
    }

    @Override
    protected void hook(int startRow, XSSFSheet xssfSheet, ExcelSheet excelSheet) {

    }
}

2、定义数据实体

**
 * @author huijing xu
 * @date 2020/9/30
 */
public class OrderDetails {
    @Column(name = "OrderId")
    @ExcelCellType(cellTyp = ExcelCellType.Type.NUMBER_INTEGER)
    private Long orderId;

    @Column(name = "OrderAmount")
    @ExcelCellType(cellTyp = ExcelCellType.Type.NUMBER_DOUBLE)
    private BigDecimal orderAmount;

    @Column(name = "OrderName")
    @ExcelCellType(cellTyp = ExcelCellType.Type.STRING)
    private String orderName;

    public Long getOrderId() {
        return orderId;
    }

    public void setOrderId(Long orderId) {
        this.orderId = orderId;
    }

    public BigDecimal getOrderAmount() {
        return orderAmount;
    }

    public void setOrderAmount(BigDecimal orderAmount) {
        this.orderAmount = orderAmount;
    }

    public String getOrderName() {
        return orderName;
    }

    public void setOrderName(String orderName) {
        this.orderName = orderName;
    }
}

3、实现AbstractGenerateExcelSheet 抽象类

/**
 * @author huijing xu
 * @date 2020/9/30
 */
@Component
public class OrderExcelSheet extends AbstractGenerateExcelSheet<OrderDetails> {

    @Override
    Field[] initFieldList() {
        return OrderDetails.class.getDeclaredFields();
    }
}
测试1:将数据集生成Excel
/**
 * @author huijing xu
 * @date 2020/9/30
 */
public class TestExcel  {
    @Autowired
    private OrderExcelSheet orderExcelSheet;
    @Autowired
    private NormalExportXlsxExcel normalExportXlsxExcel;

    @Test
    public void test() {
        // 填充数据
        OrderDetails order1 = new OrderDetails();
        order1.setOrderId(123456L);
        order1.setOrderAmount(new BigDecimal("2.5"));
        order1.setOrderName("棒棒糖");

        OrderDetails order2 = new OrderDetails();
        order2.setOrderId(666666L);
        order2.setOrderAmount(new BigDecimal("6.3"));
        order2.setOrderName("雪糕");

        List<OrderDetails> orderDetails = Arrays.asList(order1, order2);

        // 生成ExcelSheet对象
        ExcelSheet excelSheet = orderExcelSheet.generateSheet(orderDetails, "orders");

        // 生成Xlsx格式的Excel文件
        ByteArrayInputStream byteArrayInputStream = normalExportXlsxExcel.exportExcel(excelSheet);
        
        byte[] bytes = generateByte(byteArrayInputStream);
        FileOutputStream fileOutputStream = new FileOutputStream(new File("D:\\order.xlsx"));
        fileOutputStream.write(bytes);
    }

    private static byte[] generateByte(InputStream is) throws IOException {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int n = 0;

        while (-1 != (n = is.read(buffer))) {
            output.write(buffer, 0, n);
        }
        return output.toByteArray();
}

生成的效果:
在这里插入图片描述

测试2:将多个文件合并为一个文件

注意:标题行必须一致,否则取不到这列的值

文件order_other:
在这里插入图片描述

文件order_other_2:
在这里插入图片描述

@Test
public void test2() throws IOException {
    byte[] bytes = readFromByteFile("D:\\order_other.xlsx");
    byte[] bytes2 = readFromByteFile("D:\\order_other_2.xlsx");
    List<byte[]> list = Arrays.asList(bytes, bytes2);

    // 将文件转换为ExcelSheet对象
    ExcelSheet orderOtherSheet = normalExportXlsxExcel.mergeFirstSheetExcel(list);

    // 转换为自己所需要的ExcelSheet对象
    ExcelSheet excelSheet = orderExcelSheet.convertExcelSheet(orderOtherSheet, "orders2");

    // 生成Xlsx格式的Excel文件
    ByteArrayInputStream byteArrayInputStream = normalExportXlsxExcel.exportExcel(excelSheet);

    byte[] bytesOut = generateByte(byteArrayInputStream);
    FileOutputStream fileOutputStream = new FileOutputStream(new File("D:\\order2.xlsx"));
    fileOutputStream.write(bytesOut);

}


public byte[] readFromByteFile(String pathname) throws IOException {
    File filename = new File(pathname);
    BufferedInputStream in = new BufferedInputStream(new FileInputStream(filename));
    ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
    byte[] temp = new byte[1024];
    int size = 0;
    while ((size = in.read(temp)) != -1) {
        out.write(temp, 0, size);
    }
    in.close();
    byte[] content = out.toByteArray();
    return content;
}


private static byte[] generateByte(InputStream is) throws IOException {
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int n = 0;

    while (-1 != (n = is.read(buffer))) {
        output.write(buffer, 0, n);
    }
    return output.toByteArray();
}

生成的效果:
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值