Hutool工具类BigExcelWriter导出Excel调用autoSizeColumnAll()方法无法自适应列宽度的问题

看的这个人的
https://blog.csdn.net/weixin_43466094/article/details/108940721

没用啊。还是不自适应。升了包的版本也是无效。看起来比不设置稍微列宽长了一点而已

后来看github上有issue
https://github.com/looly/hutool/issues/1210

以及百度,是中文计算长度的原因

解决:
新建一个MyExcelWriter.java继承BigExcelWriter,重写autoSizeColumnAll方法

 public static MyExcelWriter getBigWriter() {
        try {
            return new MyExcelWriter();
        } catch (NoClassDefFoundError var1) {
            throw new DependencyException((Throwable) ObjectUtil.defaultIfNull(var1.getCause(), var1), "You need to add dependency of 'poi-ooxml' to your project, and version >= 4.1.2", new Object[0]);
        }
    }


 @Override
    public BigExcelWriter autoSizeColumnAll() {
        final SXSSFSheet sheet = (SXSSFSheet)this.sheet;
        sheet.trackAllColumnsForAutoSizing();
        super.autoSizeColumnAll();
        for (int i = 0; i <sheet.getRow(sheet.getLastRowNum()).getPhysicalNumberOfCells(); i++) {
            // 解决自动设置列宽中文失效的问题
            sheet.setColumnWidth(i, sheet.getColumnWidth(i) * 17 / 10);
        }
        sheet.untrackAllColumnsForAutoSizing();
        return this;
    }

使用示范:

 /**
     * test
     * @param response
     * @throws IOException
     */
    @GetMapping("/testAutoSizeColumnAll")
    public void testAutoSizeColumnAll(HttpServletResponse response) throws IOException {
        List<?> row1 = CollUtil.newArrayList("增速排名", "关键词", "slope值", "周期", "最近一周排名");
        List<?> row2 = CollUtil.newArrayList("1", "lysol", "6.00", "2020-26周 - 2020-27周", "5");
        List<?> row3 = CollUtil.newArrayList("2", "masks for coronavirus protection", "1.00", "2020-26周 - 2020-27周", "3");


        List<List<?>> rows = CollUtil.newArrayList(row1, row2, row3);


        // 通过工具类创建writer,默认创建xls格式  todo  改成get
        MyExcelWriter writer =MyExcelWriter.getBigWriter();
        // 一次性写出内容,使用默认样式,强制输出标题
        writer.write(rows, true);
        // 设置所有列为自动宽度,不考虑合并单元格
        writer.autoSizeColumnAll();


        //response为HttpServletResponse对象
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        //test.xls是弹出下载对话框的文件名,不能为中文,中文请自行编码
        response.setHeader("Content-Disposition","attachment;filename=test.xls");
        //out为OutputStream,需要写出到的目标流
        ServletOutputStream out = response.getOutputStream();

        writer.flush(out, true);
        // 关闭writer,释放内存
        writer.close();
        //此处记得关闭输出Servlet流
        IoUtil.close(out);

    }

如何获取列长度, 为第一行writer.merge做准备:
【Hutool Excel】List方式生成Excel

 //字段数量
        int fieldLength = StaffVo.class.getDeclaredFields().length;

【Hutool Excel】Map方式生成Excel

 //字段数量
        int fieldLength = rows.get(0).size();
	1. SXSSFSheet sheet = (SXSSFSheet) writer.getSheet();
	 sheet.setColumnWidth(i, sheet.getColumnWidth(i) * 17 / 10);不然它报不能自动转
	2.   writer.autoSizeColumnAll();在 writer.write(之后
	-----------------历经傍晚测试到半夜三点
	与是否BigExcel无关
	与this无关
	与是否直接调封装方法写本地还是转读取为io流网络写出无关
	与是否合并首行无关  
	与特殊字符无关
猜测与  rows 数据结构有关——只支持【行列对象List:行列对象List<List<?>>】写出的方式,才autoSizeColumnAll
	
	都错。
	
	尼玛,不经意限制rows长度后(本意是想把线上数据黏贴一两条出来[列较多],放本地psvm里运行看excel效果是否有变化),发现数据量小时,正常自适应了!数据量大时,就会失效(99可行,100条不行。  ThreadUtil.sleep(30*1000);无效
	好巧的数字【妈的,早知道debug了,浪费我这么多时间在这测。这就是不自信debug的下场吗。这估计是为了BigExcel效率而特地限制的吧】,感觉像人为限制的呢,果然,点进源码发现SXSSFSheet _randomAccessWindowSize
	

原因:
破案了,是BigExcel机制的原因:
https://blog.csdn.net/zlp5201/article/details/21611673

 比如内存中限制行数为100,当行号到达101时,行号为0的记录刷新到硬盘并从内存中删除,当行号到达102时,行号为1的记录刷新到硬盘,并从内存中删除,以此类推。

       rowAccessWindowSize代表指定的内存中缓存记录数,默认为100,此值可以通过

new SXSSFWorkbook(int rowAccessWindowSize)或SXSSFSheet.setRandomAccessWindowSize(intwindowSize)来设置。

不过,
sheet.setRandomAccessWindowSize(10000);
无效。

 SXSSFSheet sheet = (SXSSFSheet) writer.getSheet();
        sheet.setRandomAccessWindowSize(5000);

无效。 2020年11月28日 03:55:59

或者是因为我直接写入磁盘得原因,100一次。虽重设无用。
如果写到流呢,会存在100一写的可能吗,会重设有用吗。【没试,但估计指定不可能:flushout又不管你写到哪】

或者换Writer类型【所有对生成后数据样式操作都受此机制影响,比如改[行高]。我这儿[自适应]不就是[列宽],和它一码事。】

试试其他方式产生excel能否自适应宽(少量数据时),估计能,因为特么原理明白了:【没试,但估计指定不可能:生成后设置得自适应。这三种方式只是不同的在内存中制造excel的方式而已,而设置自适应又不在这呢。】https://blog.csdn.net/zhangjinwei417/article/details/99413184
试了,BigExcel时,setRandomAccessWindowSize(-1),没用-_-||

【你为了效率都不改fastdfs名了,都异步了,就不该还做自适应这种影响生成效率的行为了。手动重设列宽效率还行,可以接受。】

  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值