目 录CONTENT

文章目录

Word模板导出时自动分页

javalx
2025-01-09 / 0 评论 / 0 点赞 / 160 阅读 / 0 字

Word模板导出时自行分页

word模板导出后存在跨页问题,这样会影响打印纸质排版,需要导出时自动进行分页,避免模板跨页。

需求背景

甲方为了方便对第三方单位人员进行监管,要求根据委外人员信息导出委外人员证件,即word导出。

word模板如下:

问题描述

由于导出后的word是需要用于打印制作实体证件用,且模板高度不能完整整数倍适配页面高度,因此在导出多页数据时会出现单个模板数据跨页的现象,导致打印时个别证件无法完整制作。

解决方案

根据每页能放下的完整模板数代码进行分页(插入分页符)

  • 依赖配置

    <poi.version>4.1.2</poi.version>
    <poi-tl.version>1.10.0</poi-tl.version>
    <!-- 导出工具 -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>${poi.version}</version>
    </dependency>
    
    <!-- word模板工具 -->
    <dependency>
        <groupId>com.deepoove</groupId>
        <artifactId>poi-tl</artifactId>
        <version>${poi-tl.version}</version>
    </dependency>
    
  • java代码

    // Controller
    
    @ApiOperation("导出委外单位人员证")
    @ApiOperationSupport(order = 9)
    @PostMapping("/exportProof")
    @Log(title = "委外人员", businessType = BusinessType.EXPORT)
    public void exportProof(HttpServletResponse response, EntrustUserDTO dto) throws IOException {
        List<EntrustUserVO> expData = entrustUserService.getExpData(dto);
        for (int i = 0; i < expData.size(); i++) {
            EntrustUserVO entrustUserVO = expData.get(i);
            Boolean needPageBreak = i > 0 && ((i + 1) % 4 == 0);
            entrustUserVO.setNeedPageBreak(needPageBreak);
        }
        response.setContentType("application/octet-stream");
        response.setHeader("Content-disposition", "attachment");
        response.setCharacterEncoding("utf-8");
        // 这里绑定了一个自定义的插件到isPageBreak标签
        Configure config = Configure.builder().useSpringEL().bind("needPageBreak",
                new AbstractRenderPolicy<Boolean>() {
                    @Override
                    public void doRender(RenderContext<Boolean> context) throws Exception {
                        XWPFRun where = context.getWhere();
                        boolean thing = context.getThing();
                        where.setText("", 0);
                        if (thing)
                            where.addBreak(BreakType.PAGE);
                    }
                }).build();
        // 读取模板流,组装数据
        InputStream inputStream = ImageUtils.getOssStream("ucd-oss-priv/template/word/credentials.docx");
        XWPFTemplate template = XWPFTemplate.compile(inputStream, config).render(
                new HashMap<String, Object>() {
                    {
                        put("rows", expData);
                    }
                }
        );
        template.writeAndClose(response.getOutputStream());
    }
    
    // Service
    
    @Override
    public List<EntrustUserVO> getExpData(EntrustUserDTO dto) {
        List<Long> ids = dto.getIds();
        LambdaQueryWrapper<EntrustUser> queryWrapper = new LambdaQueryWrapper<EntrustUser>()
                .in(EntrustUser::getId, ids)
                .eq(EntrustUser::getStatus, "2")
                .select(
                        EntrustUser::getId,
                        EntrustUser::getContractId,
                        EntrustUser::getAgreementId,
                        EntrustUser::getName,
                        EntrustUser::getEntrustNo,
                        EntrustUser::getDeptName,
                        EntrustUser::getStatus,
                        EntrustUser::getAvatar
                );
        List<EntrustUser> entrustUsers = entrustUserMapper.selectList(queryWrapper);
        if (CollectionUtil.isEmpty(entrustUsers)) {
            return new ArrayList<>();
        }
        List<EntrustUserVO> collect = entrustUsers.stream().map(e -> {
            EntrustUserVO entrustUserVO = mapStruct.do2Vo(e);
            Long contractId = entrustUserVO.getContractId();
            Long agreementId = entrustUserVO.getAgreementId();
            Contract contract = contractMapper.selectById(contractId);
            SafeAgreement safeAgreement = safeAgreementMapper.selectById(agreementId);
            String unitName = contract.getUnitName();
            Date endDate = safeAgreement.getEndDate();
            entrustUserVO.setUnitName(unitName);
            Date date = new Date();
            int compare = DateUtil.compare(date, endDate);
            if (compare >= 0) {
                entrustUserVO.setDate("已失效");
            } else {
                DateTime dateTime = DateUtil.offsetMonth(date, 12);
                compare = DateUtil.compare(dateTime, endDate);
                endDate = compare <= 0 ? dateTime : endDate;
                entrustUserVO.setDate(
                        StringUtils.format("{} ~ {}",
                                DateUtil.format(date, "yyyy-MM-dd"),
                                DateUtil.format(endDate, "yyyy-MM-dd")
                        )
                );
            }
            // 处理图片格式
            String avatar = e.getAvatar();
            if (StringUtils.isNotBlank(avatar)) {
                byte[] data = ImageUtils.getImage(avatar);
                String extName = FileNameUtil.extName(avatar);
                extName = extName.toLowerCase();
                PictureType pictureType = FileUtils.getExtension(extName);
                entrustUserVO.setAvtData(new PictureRenderData(90, 90, pictureType, data));
            }
            return entrustUserVO;
        }).collect(Collectors.toList());
        return collect;
    }
    
    // VO实体
    
    package com.ucd.outer.domain.vo;
    
    import com.deepoove.poi.data.PictureRenderData;
    import com.fasterxml.jackson.annotation.JsonFormat;
    import com.ucd.common.annotation.OssFiled;
    import com.ucd.common.core.domain.BaseVO;
    import com.ucd.common.annotation.Excel;
    import com.ucd.outer.domain.entity.EntrustUserDanger;
    import io.swagger.annotations.ApiModel;
    import io.swagger.annotations.ApiModelProperty;
    import lombok.Data;
    
    import java.util.Date;
    import java.util.List;
    
    /**
     * 委外人员对象 outer_entrust_user
     *
     * @author javalx
     * @date 2023-04-10 16:05:59
     */
    @Data
    @ApiModel(value = "EntrustUserVO", description = "委外人员VO")
    public class EntrustUserVO extends BaseVO{
        private static final long serialVersionUID = 1L;
    
        @Excel(name = "ID", cellType = Excel.ColumnType.NUMERIC, width = 20, needMerge = true)
        @ApiModelProperty(value = "ID")
        private Long id;
        @ApiModelProperty(value = "合同ID")
        private Long contractId;
        @ApiModelProperty(value = "安全协议ID")
        private Long agreementId;
        @Excel(name = "安全协议编号", needMerge = true)
        @ApiModelProperty(value = "安全协议编号")
        private String agreementNo;
        @Excel(name = "性别", readConverterExp = "0=男,1=女,2=未知", needMerge = true)
        @ApiModelProperty(value = "性别")
        private String sex;
        @Excel(name = "岗位", needMerge = true)
        @ApiModelProperty(value = "岗位")
        private String post;
        @Excel(name = "身份证号", needMerge = true)
        @ApiModelProperty(value = "身份证号")
        private String idNumber;
        @Excel(name = "联系电话", needMerge = true)
        @ApiModelProperty(value = "联系电话")
        private String phone;
        @Excel(name = "地址", needMerge = true)
        @ApiModelProperty(value = "地址")
        private String address;
        @ApiModelProperty(value = "危险作业人员(是:1,否:2)")
        private String danger;
        @ApiModelProperty(value = "所属中心ID(中心XXX:1)")
        private Long deptId;
        @ApiModelProperty(value = "所属车间ID(车间XXX:1)")
        private Long workshopId;
        @Excel(name = "所属车间", needMerge = true)
        @ApiModelProperty(value = "所属车间")
        private String workshopName;
        @Excel(name = "所属工区", needMerge = true)
        @ApiModelProperty(value = "所属工区")
        private String workarea;
        @Excel(name = "作业内容", needMerge = true)
        @ApiModelProperty(value = "作业内容")
        private String jobContent;
        @ApiModelProperty(value = "发证日期结束")
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private Date trainingDate;
        @ApiModelProperty(value = "培训状态(未通过:1,已通过:2)")
        private String status;
        @ApiModelProperty(value = "备注")
        private String remark;
        @ApiModelProperty(value = "有效期(截止)")
        private Date endDate;
        @OssFiled
        @ApiModelProperty(value = "照片")
        private String avatar;
        @Excel(name = "特种作业证书")
        @ApiModelProperty(value = "特种作业证书")
        private List<EntrustUserDangerVO> dangers;
        
        
        // word模板导出数据
        @Excel(name = "姓名", needMerge = true)
        @ApiModelProperty(value = "姓名")
        private String name;
        @Excel(name = "委外证号", needMerge = true)
        @ApiModelProperty(value = "委外证号")
        private String entrustNo;
        @Excel(name = "所属部门", needMerge = true)
        @ApiModelProperty(value = "所属部门")
        private String deptName;
        @ApiModelProperty(name = "有效期")
        private String date;
        @ApiModelProperty(name = "单位名称")
        private String unitName;
        @ApiModelProperty(value = "照片")
        private PictureRenderData avtData;
        @ApiModelProperty(value = "是否需要分页")
        private Boolean needPageBreak;
    }
    
    
  • 导出模板

  • 导出效果

0

评论区