首页 > 其他分享 >关于easyExcel导出文字合并居中和服务器导出失败踩了一天的坑

关于easyExcel导出文字合并居中和服务器导出失败踩了一天的坑

时间:2024-03-15 17:56:52浏览次数:24  
标签:sheet 导出 easyExcel cellPrev excel cell import 服务器 com

参考:https://blog.csdn.net/hanyi_/article/details/118117484,https://blog.csdn.net/sunyuhua_keyboard/article/details/125482353,https://lhalcyon.com/alpine-font-issue/,https://github.com/alibaba/easyexcel/issues/1476(没字体)

 

首先吧,因为每周列会需要看用户使用情况报表,我这边需要把整合好的数据整理下给产品,但我比较追求便捷化,想一次性做成并导出成excel,上回直接拿导出的sql已经够难看了,这回想做个全面自动化,接着就是行动,需求是看到用户使用的多个设备的不同使用时长情况,这个其实很简单无非就是把用户跟设备一条条全查出来,挨的近些到时候直接合并并居中就好了,昨天已经做成了导出一条条数据的excel,今天就是想在原来基础上合并并居中再上线测试。

于是我开始了第一步,找了好多easyExcel合并单元格的文章最终确定了一个使用strategy策略用Excel.write方式去实现的,同时辨别如果是相同的就合并单元格

 

以下是CustomMergeStrategy的代码



import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;


import java.util.List;

public class CustomMergeStrategy implements CellWriteHandler {
    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        if (isHead){
            //如果是表头不做处理
            return;
        }
        //如果当前是第一行不做处理
        if(relativeRowIndex==0){
            return;
        }

        //获取当前行下标,上一行下标,上一行对象,上一列对象
        Sheet sheet = cell.getSheet();
        int rowIndex = cell.getRowIndex();
        int rowIndexPrev=rowIndex- 1;
        Row row = sheet.getRow(rowIndexPrev);
        Cell cellPrev = row.getCell(cell.getColumnIndex());

        //得到当前单元格值和上一行单元格
//        Object cellValue =cell.getCellType()== CellType.STRING?cell.getStringCellValue() : cell.getNumericCellValue();
//        Object cellValuePrev =cellPrev.getCellType()==CellType.STRING?cellPrev.getStringCellValue():cellPrev.getNumericCellValue();
        String cellValue =cell.getCellType()== CellType.STRING?cell.getStringCellValue() : String.valueOf(cell.getNumericCellValue());
        String cellValuePrev =cellPrev.getCellType()==CellType.STRING?cellPrev.getStringCellValue():String.valueOf(cellPrev.getNumericCellValue());

        System.out.println("cellValuePrev = " + cellValuePrev);
        System.out.println("cellValue = " + cellValue);
        //如果当前单元格和上一行单元格值相等就向下执行合并
        // 这边if不能调顺序
        if (StringUtils.isEmpty(cellValue) && StringUtils.isEmpty(cellValuePrev)){
            return;
        }
        if (!cellValue.equals(cellValuePrev)) {
            return;
        }

        //获取已有策略
        List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();

        boolean mergen=false;
        for (int i = 0; i < mergedRegions.size(); i++) {
            CellRangeAddress cellAddresses = mergedRegions.get(i);
            if(cellAddresses.isInRange(rowIndexPrev,cell.getColumnIndex())){
                sheet.removeMergedRegion(i);
                cellAddresses.setLastRow(rowIndex);

                sheet.addMergedRegion(cellAddresses);
                mergen=true;
                break;
            }

        }
        if (!mergen){
            CellRangeAddress cellAddresses = new CellRangeAddress(rowIndexPrev, rowIndex, cell.getColumnIndex(), cell.getColumnIndex());
            sheet.addMergedRegion(cellAddresses);

        }

    }

}

然后被我业务代码调用实现

EasyExcel.write("/app/static/用户统计"+dateStr+".xlsx")
        .head(UserTimeLengthExcelItemDTO.class)
        .registerWriteHandler(new CustomMergeStrategy())
        .sheet("用户统计").doWrite(tmpUserTimeLengthExcelItemDTOList);

ok以上代码就简单实现了excel导出和合并单元格,接着我看到

这个样子有点丑啊,至少要居中吧,于是找了很多甚至还想多谢个策略类然后把add到registerWriteHandler这个里面去,不过没有成功,一直报错,继续想办法不断百度百度,都不大行,那就算了我就google看下好了哇,google出来第一个说加个注解就行了,于是我便到导出dto上面加

@HeadStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER)

在执行下果然可以,看下效果图,

发现还有点别扭啊,这个字居中是居中了,但是在底部不好看啊,继续找上下居中,查了下还是注解上加

@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, verticalAlignment = VerticalAlignmentEnum.CENTER)//内容样式

这样子就可以了嘛,发现还有问题,空的和空的合并了,但是他们不是一个用户下的,没有截图,于是我想应该要加个判断如果是空的就不要合并,看了下逻辑他只是对如果是空就就合并做了判断,我就在上头加了个空的判断吗,ok这样子一个令人满意的报表就生成好了。

上传到线上,然后尝试生成excel,看到报错

ERROR c.c.platform.core.exception.GlobalExceptionHandler - 未知异常!原因是:ExcelGenerateException: java.lang.NoClassDefFoundError: Could not initialize class sun.awt.X11FontManager

没找到,按我在本地时候以为是文件夹不存在或者没有权限,我就去改保存的文件夹路径,前后改了3次都不成功,于是我好好看了报错内容再去google上查下发现有人说这个是没有找到字体的原因,好吧,没有字体我就装字体好吧,先apt updatealiyun真的慢等了很久终于好了,再执行命令

apt-get install -y fonts-dejavu libfreetype6-dev fontconfig

也等了好久终于好了,然后尝试继续报错,我想不应该呀,我先重启容器再说,果然我再次请求生成就可以了,好吧这样子的话我只能把当前容器再打个镜像以后就以这个新镜像跑了,想起之前有个人评论说的可能是你的镜像是silm的原因,我想我要不要看下Dockerfile里用的是啥,果然看到用的FROM openjdk:17-slim,乖乖,保底的有了,我要把这个silm删了再试试,等了一会容器起来了,在尝试生成下,成功!

md,折腾了靠一天,终于好了,拜拜,去搞scoop了

标签:sheet,导出,easyExcel,cellPrev,excel,cell,import,服务器,com
From: https://www.cnblogs.com/warrenwt/p/18075945

相关文章

  • django实现将后台数据excel文件形式导出
    视图函数export_persons引入导出excle相关库importxlwtdefexport_persons(request):#获取数据库中的所有Project对象persons=m1.Project.objects.all()#创建Excel文件book=xlwt.Workbook(encoding='utf-8',style_compression=0)sheet=book.add_sheet('Sheet',......
  • node.js服务器
    Node.js发布于2009年5月,由RyanDahl开发,是一个基于ChromeV8引擎的JavaScript运行环境,使用了一个事件驱动、非阻塞式I/O模型,[1]让JavaScript运行在服务端的开发平台,它让JavaScript成为与PHP、Python、Perl、Ruby等服务端语言平起平坐的脚本语言。简单来说,就是让原本运行在客户端......
  • 服务器反向代理的作用与实现
    目录前言一、服务器反向代理的作用1.负载均衡2.缓存控制3.安全防护4.单一入口二、服务器反向代理的实现方式 三、总结前言服务器反向代理是一种通过将客户端的请求转发给多个服务器中的一台来分担服务器负载的网络技术。本文将介绍服务器反向代理的作用、实现......
  • Write failed: Broken pipe > Couldn‘t read packet: Connection reset by peer SFTP
    如果你链接服务器的时候出现下面的提示:Writefailed:BrokenpipeCouldn’treadpacket:Connectionresetbypeer这个问题的原因是ChrootDirectory的权限问题,你设定的目录必须是root用户所有,否则就会出现问题。所以请确保sftp用户根目录的所有人是root,权限是750或者755。......
  • 腾讯云服务器Nginx反向代理的Photoprism(包括https设置)
    2024年3月15日,因为不想忘记前面关于Nginx反向代理Photoprism的内容。这里记录下,如果能帮助到点击到这篇博客的人就更好了。主要分为三个部分,第一个部分是部署Photoprism,第二个部分是Nginx反向代理,第三个部分是https设置前置条件(没有的话,就不要往下看了,或者先稍微了解下再往下看)......
  • STM32F105双路隔离型CAN总线转4G控制板 - 把CAN数据发送到TCP服务器,实现通过TCP透传
    <p><iframename="ifd"src="https://mnifdv.cn/resource/cnblogs/product/STM32F105_2CAN/index.html"frameborder="0"scrolling="auto"width="100%"height="1500"></iframe></p>......
  • Kibana导出查询结果
    查询Exchange服务器上的安全事件日志,通过攻击源客户端计算机名称,获取攻击源IP  Visualize-新建-Datatable-索引定义好过滤条件后,根据访问源IP进行分组,并统计访问次数,然后导出结果 定义好过滤条件后,导出被爆破的用户名,并统计次数,然后导出结果 通过直方图统计......
  • python的代码发布到服务器上需要注意的事项
    1、服务器的python运行环境配置。从官网上 https://www.python.org/ 下载服务器操作系统对应的版本。 然后配置 python和pip命令运行的环境变量,这是windows下的 检查是否正常:  2、开发时引用的第三方库要在服务器上安装。   a.首先获取需要的第三方库......
  • 【PG】ora2pg 分别导出表,索引,存储过程等
    #!/bin/bash#检查ora2pg命令是否可用command-vora2pg>/dev/null2>&1||{echo>&2"ora2pg工具未安装或未在PATH中。请先安装并配置好ora2pg工具。";exit1;}#配置文件路径ora2pg_conf="/path/to/ora2pg.conf"#导出表结构和数据echo"导出表结构和数据..."......
  • 使用EasyExcel读取Excel文件遇到的小问题
    没有读取到内容的问题excel内容具体代码importcom.alibaba.excel.EasyExcel;importcom.alibaba.excel.annotation.ExcelProperty;importjava.io.File;importjava.util.List;publicclassTestEasyExcel{publicstaticvoidmain(String[]args){Lis......