jxls——自定义命令设置动态行高

文章目录

前言

之前的博客中都简单说了数据的渲染和导出excel文件。包括固定的 表头结构,以及动态 表头和表数据等方式。

本篇博客主要说明自定义命令的方式,控制输出excel文件每行记录的行高

依赖引入

主要依赖以及版本如下所示:

xml 复制代码
<dependency>
    <groupId>org.jxls</groupId>
    <artifactId>jxls</artifactId>
    <version>2.4.5</version>
</dependency>
<dependency>
    <!-- 可以使用poi的实现也可以用jexcelapi的 -->
    <groupId>org.jxls</groupId>
    <artifactId>jxls-poi</artifactId>
    <version>1.0.15</version>
</dependency>
<dependency>
    <groupId>org.jxls</groupId>
    <artifactId>jxls-jexcel</artifactId>
    <version>1.0.7</version>
</dependency>
<dependency>
    <groupId>net.sf.jxls</groupId>
    <artifactId>jxls-core</artifactId>
    <version>1.0.6</version>
</dependency>

绘制 jxls 批注的 excel 模板

其中两个批注分别如下:

  • 整体数据范围:

    Administrator:

    jx:area(lastCell="H3")

  • 列表数据渲染范围:

    Administrator:

    jx:each(items="bDatas" var="vo" lastCell="H3" varIndex="ojbIndex" )

测试类编写

编写一个简单的数据填充逻辑,并生成对应的excel文件。代码如下所示:

java 复制代码
import cn.xj.test.UserPo;
import com.google.common.collect.Lists;
import org.jxls.builder.xls.XlsCommentAreaBuilder;
import org.jxls.common.Context;
import org.jxls.util.JxlsHelper;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import java.io.*;
import java.util.*;

public class Test1 {

    public static void main(String[] args) throws IOException {
        Context context = new Context();
        // 数据集合
        List<UserPo> dataList = Lists.newArrayList();
        for (int i = 0; i < 10; i++) {
            UserPo userPo = new UserPo();
            userPo.setNum("1_"+i);
            userPo.setName("xj_"+i);
            userPo.setAge(i+1);
            userPo.setMail("专注写bug测试中文11111");
            dataList.add(userPo);
        }
        // ${item.num}
        context.putVar("bDatas",dataList);

		// 模板文件再resources 目录下
        Resource resource = new ClassPathResource("/report/test_user1.xlsx");
        InputStream is = resource.getInputStream();

        String outFile = System.getProperty("user.dir")+ File.separator+"springboot-poi"+File.separator+"pdf"+File.separator+System.currentTimeMillis()+ ".xlsx";
        OutputStream outputStream = new FileOutputStream(outFile);

        JxlsHelper jxlsHelper = JxlsHelper.getInstance();
        jxlsHelper.getAreaBuilder().getTransformer();
        jxlsHelper.processTemplate(is, outputStream, context);
		
		// JxlsHelper.getInstance().processTemplate(is, outputStream, context);
    }
}

执行后,生成excel文件中内容的效果如下所示:

每行的行高太大,毕竟再模板中就是配置的这么大,显得很散乱。此时则可以使用自定义命令的方式,动态地修改行高

自定义命令

jxls中自定义命令,可以采取继承 AbstractCommand 类实现。自定义命令需要定义命令名称命令逻辑。如下所示:

java 复制代码
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.jxls.area.Area;
import org.jxls.command.AbstractCommand;
import org.jxls.common.CellRef;
import org.jxls.common.Context;
import org.jxls.common.Size;
import org.jxls.transform.poi.PoiTransformer;

/**
 * 自定义列高指令
 * 如:
 * jx:autoRowHeight(lastCell ="C3")
 *
 * 还需要在对应的主程序中调用
 */
public class AutoRowHeightCommand extends AbstractCommand {

    /**
     * 批注中的自定义指令
     * @return
     */
    @Override
    public String getName() {
        return "autoRowHeight";
    }

    /**
     * 列高逻辑
     * @param cellRef
     * @param context
     * @return
     */
    @Override
    public Size applyAt(CellRef cellRef, Context context) {
        Area area=getAreaList().get(0);
        Size size = area.applyAt(cellRef, context);

        PoiTransformer transformer = (PoiTransformer) area.getTransformer();

        Sheet sheet = transformer.getWorkbook().getSheet(cellRef.getSheetName());
//        List bDatas = (List) context.getVar("bDatas");
//        int firstDefaultCol = cellRef.getCol(); // 最开始的第一列
//        if(!CollectionUtils.isEmpty(bDatas)){
//            for (int i = 0; i < bDatas.size(); i++) {
//                // 计算中文、字符的长度  设定列宽
//                Object data = bDatas.get(i);
//                if(!StringUtils.isEmpty(data) && (data.getBytes().length+4)>sheet.getColumnWidth(i)){
//                    sheet.setColumnWidth(i+firstDefaultCol,data.getBytes().length+4);
//                }else{
//                    sheet.setColumnWidth(i+firstDefaultCol,30); // 默认
//                }
//
//            }
//        }
        //sheet.setColumnWidth(cellRef.getCol(),50);

        Row row = sheet.getRow(cellRef.getRow());
        row.setHeight((short) -1);

        return size;
    }
}

自定义命令后,需要再模板中增加命令的标识,否则不会生效。

jx:autoRowHeight(lastCell ="H3")

其次,还需要再调用jxls做填充渲染之前,补充命令和逻辑的调用。

java 复制代码
import cn.xj.jxls.AutoRowHeightCommand;
import cn.xj.test.UserPo;
import com.google.common.collect.Lists;
import org.jxls.builder.xls.XlsCommentAreaBuilder;
import org.jxls.common.Context;
import org.jxls.util.JxlsHelper;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import java.io.*;
import java.util.*;

public class Test1 {

    public static void main(String[] args) throws IOException {
        Context context = new Context();
        // 数据集合
        List<UserPo> dataList = Lists.newArrayList();
        for (int i = 0; i < 10; i++) {
            UserPo userPo = new UserPo();
            userPo.setNum("1_"+i);
            userPo.setName("xj_"+i);
            userPo.setAge(i+1);
            userPo.setMail("专注写bug测试中文11111");
            dataList.add(userPo);
        }
        // ${item.num}
        context.putVar("bDatas",dataList);

        // 模板文件再resources 目录下
        Resource resource = new ClassPathResource("/report/test_user1.xlsx");
        InputStream is = resource.getInputStream();

        String outFile = System.getProperty("user.dir")+ File.separator+"springboot-poi"+File.separator+"pdf"+File.separator+System.currentTimeMillis()+ ".xlsx";
        OutputStream outputStream = new FileOutputStream(outFile);

        JxlsHelper jxlsHelper = JxlsHelper.getInstance();
        jxlsHelper.getAreaBuilder().getTransformer();
        // 渲染前  载入 自定义 命令
        XlsCommentAreaBuilder.addCommandMapping("autoRowHeight", AutoRowHeightCommand.class);
        jxlsHelper.processTemplate(is, outputStream, context);
    }
}

执行后的效果如下所示:

关于自动换行

jxls没有对应的自动换行操作,但是jxls可以在模板中定义对应的单元格样式。只需要在模板中对需要做自动换行的列增加如下配置。

再次执行上述的代码逻辑,查看显示效果。

相关推荐
脉动数据行情137 分钟前
Java SpringBoot 国际期货批量采集实践 美原油 / 黄金 / 指数期货定时落库
java·开发语言·spring boot
Zzzzmo_2 小时前
SpringBoot 日志
java·spring boot·spring
计算机毕设定制辅导-无忧学长2 小时前
《基于SpringBoot的家政服务管理平台的设计与实现》
java·vue.js·spring boot·计算机毕业设计选题推荐·家政服务管理平台
xiaoqiMikko2 小时前
pom 里没有、代码里没调过,但 WebClient 默认用的就是 netty-resolver-dns
java·spring boot
xixingzhe23 小时前
spring boot对接Dify
java·spring boot·dify
步行cgn3 小时前
Spring Boot 指定数据来源详解
spring boot·后端·python
一个有温度的技术博主3 小时前
深入理解 Spring Boot 自动装配
java·spring boot·后端
步行cgn5 小时前
Spring Boot 将配置绑定到第三方对象详解
spring boot·后端·python
凤山老林5 小时前
Spring Boot 集成 Apache Kafka Streams 构建流处理应用:状态存储、窗口聚合与
spring boot·kafka·apache
Flynt17 小时前
把公司项目迁到 Spring Boot 4.0:编译通过只是开始
java·spring boot·后端