java 利用poi根据excel模板导出数据(二)

本文是  java 利用poi根据excel模板导出数据(一) 的续篇

经常有poi的开发一定会碰到三个名词:

HSSFWorkbook 、 XSSFWorkbook、SXSSFWorkbook;

这三个都是导出excel的形式,具体区别:

HSSFworkbook,XSSFworkbook,SXSSFworkbook区别总结

我们在上篇用的是XSSFWorkbook,上篇我这边需求最多100行,所以用了XSSFworkbook,

但是由于需求不同、所导出的数据量不同,包括导出的文件大小等等,应选择不同的形式。考虑到别的需求有超过65535的,本文就以SXSSFworkbook来补充上篇

因为SXSSFworkbook在使用Excel模板下载数据时将不能直接动态改变表头,所以我们需要

去获取初始模板的行数据,并操作。

首先,我们直接把XSSFworkbook 改成SXSSFworkbook,看看会有什么效果

为什么getRow是空呢?

SXSSFWorkbook是streaming版本的XSSFWorkbook,它只会保存最新的excel rows在内存里供查看,在此之前的excel rows都会被写入到硬盘里(Windows电脑的话,是写入到C盘根目录下的temp文件夹)。被写入到硬盘里的rows是不可见的/不可访问的。只有还保存在内存里的才可以被访问到。

还有就是,模板数据存在于XSSFWorkbook中,你需要用sxssfWorkbook.getXSSFWorkbook()方法去获取初始模板的行数据。

为什么POI模板中的数据获取不到?

我们来试试 (只贴修改的方法代码,其他的和上篇一样)

  public static void doExportLongArrearsData() {
        // 要导出的数据
        NutMap nutMap = NutMap.NEW();
        nutMap.addv("comm","1111");
        nutMap.addv("a","1111");
        nutMap.addv("b","2222");
        nutMap.addv("c","11333311");
        nutMap.addv("d","1114441");
        nutMap.addv("e","555");
        nutMap.addv("f","6666");
        nutMap.addv("g","7777");
        nutMap.addv("h","88888");
        List<NutMap> list = Lists.newArrayList();
        list.add(nutMap);
        // 导出列  列数
        int colNum = 9;
        int[] colWidth = new int[colNum];
        for (int i = 0; i < colNum; i++) {
            colWidth[i] = 23;
        }
        // 从XX行开始为数据内容  excel 第一行为0
        int startRow = 5;
        //  2003版本的Excel (xls) ---- HSSFWorkbook
        //    2007版本以及更高版本 (xlsx)---- XSSFWorkbook
        //    2007版本以及更高版本 (xlsx)---- SXSSFWorkbook
        //SXSSF与XSSF的对比:
        //
        //a. 在一个时间点上,只可以访问一定数量的数据
        //
        //b. 不再支持Sheet.clone()
        //
        //c. 不再支持公式的求值
        //
        //d. 在使用Excel模板下载数据时将不能动态改变表头,因为这种方式已经提前把excel写到硬盘的了就不能再改了
        SXSSFWorkbook workbook = null;
        try {
            // 此处linux和windows通用   /files/cq.xlsx 在resource目录下  视情况而定
 
        /**
             *   特殊说明: this.getClass().getResourceAsStream 
             *   如果fileUrl路径前不加 / 那么会读取类文件夹下的文件。加了才会读取resource下面的文件
             *   exp: this.getClass().getResourceAsStream("/files/cq.xlsx") ==>读取resource下面的文件
             *   this.getClass().getResourceAsStream("files/cq.xlsx") ==>读取当前类下的文件
             *   源码:
             *     private String resolveName(String name) {
             *         if (name == null) {
             *             return name;
             *         }
             *         if (!name.startsWith("/")) {
             *             Class<?> c = this;
             *             while (c.isArray()) {
             *                 c = c.getComponentType();
             *             }
             *             String baseName = c.getName();
             *             int index = baseName.lastIndexOf('.');
             *             if (index != -1) {
             *                 name = baseName.substring(0, index).replace('.', '/')
             *                     +"/"+name;
             *             }
             *         } else {
             *             name = name.substring(1);
             *         }
             *         return name;
             *     }
             */
            //  InputStream inputStream = this.getClass().getResourceAsStream("/files/cq.xlsx");
            FileInputStream inputStream = new FileInputStream( new File("C:\\Users\\usaer\\Desktop\\buss.xlsx"));
            XSSFWorkbook xssfWorkbook = new XSSFWorkbook(inputStream);
            workbook = new SXSSFWorkbook(xssfWorkbook);
 // 获取sheet
            XSSFSheet sheetAt = xssfWorkbook.getSheetAt(0);
 
            // 动态列  修改表头名 、修改模板数据等操作
            // 自定义参数
            int k = 1;
            updateCellLoad(workbook,sheetAt ,k);
 
            // 填充数据
            fillBodyData( sheetAt ,startRow,list,colWidth);
 
          // 设置单元格宽度 (不设置就是模板宽度)
            if (null != colWidth) {
                for (int i = 0; i < colWidth.length; i++) {
                    sheetAt.setColumnWidth(i, colWidth[i] * 256 + 184);
                }
            }
 
            // 输出流
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            // excel工作空间写入流
            workbook.write(byteArrayOutputStream);
            InputStream wrap = Streams.wrap(byteArrayOutputStream.toByteArray());
            // 写到本地
            writeToLocal("C:\\Users\\usaer\\Desktop\\buss_"+k+".xlsx",wrap);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        } finally {
            // 关闭流
            if (null != workbook)
                try {
                    workbook.close();
// SXSSFWorkbook 
                    workbook.dispose();
                }
                catch (IOException e) {
 
                }
        }
    }

 

这样就可以修改导出的表头等信息了

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!您可以使用JavaPOI库来根据现有的模板导出Excel文件。下面是一个简单的示例代码,演示了如何使用POI来实现这个需求: ```java import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.*; public class ExcelExportExample { public static void main(String[] args) { String templatePath = "path/to/template.xlsx"; String outputPath = "path/to/output.xlsx"; try { FileInputStream fis = new FileInputStream(templatePath); Workbook workbook = new XSSFWorkbook(fis); Sheet sheet = workbook.getSheetAt(0); // 在模板中找到需要填充数据的位置,假设要填充的单元格是A1 Row row = sheet.getRow(0); Cell cell = row.getCell(0); // 填充数据到单元格中 cell.setCellValue("Hello, World!"); // 将修改后的Excel文件写入输出流 FileOutputStream fos = new FileOutputStream(outputPath); workbook.write(fos); // 关闭资源 fos.close(); workbook.close(); System.out.println("Excel导出成功!"); } catch (IOException e) { e.printStackTrace(); } } } ``` 在上述代码中,您需要将`templatePath`替换为实际的模板文件路径,`outputPath`替换为导出Excel文件保存路径。然后,您可以通过`Workbook`对象获取要填充数据的单元格,并使用`setCellValue`方法将数据填充到单元格中。最后,通过`FileOutputStream`将修改后的Excel写入到输出流中。 希望这个示例对您有帮助!如果您有任何其他问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值