Browse Source

发票合同代码

chen 2 weeks ago
parent
commit
ad14c0880a

+ 67 - 0
yudao-module-contract/yudao-module-contract-biz/src/main/java/cn/iocoder/yudao/module/contract/controller/admin/invoice/InvoiceController.java

@@ -1,12 +1,22 @@
 package cn.iocoder.yudao.module.contract.controller.admin.invoice;
 
+import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.ObjectUtil;
+import cn.iocoder.yudao.framework.common.exception.ServiceException;
+import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
 import cn.iocoder.yudao.module.contract.controller.admin.order.vo.OrderSyncReqVO;
+import cn.iocoder.yudao.module.contract.dal.dataobject.company.CompanyDO;
 import cn.iocoder.yudao.module.contract.dal.dataobject.invoice.InvoiceDetailsDO;
 import cn.iocoder.yudao.module.contract.dal.dataobject.invoice.InvoiceOrdersDO;
+import cn.iocoder.yudao.module.contract.dal.dataobject.invoiceContract.InvoiceContractDO;
 import cn.iocoder.yudao.module.contract.dal.dataobject.order.OrderDO;
 import cn.iocoder.yudao.module.contract.dal.dataobject.orderContract.OrderContractDO;
+import cn.iocoder.yudao.module.contract.dal.mysql.invoice.InvoiceDetailsMapper;
+import cn.iocoder.yudao.module.contract.service.company.CompanyService;
+import cn.iocoder.yudao.module.contract.service.invoice.InvoiceOrdersService;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import org.springframework.web.bind.annotation.*;
 import javax.annotation.Resource;
 import org.springframework.validation.annotation.Validated;
@@ -18,8 +28,10 @@ import io.swagger.v3.oas.annotations.Operation;
 import javax.validation.constraints.*;
 import javax.validation.*;
 import javax.servlet.http.*;
+import java.math.BigDecimal;
 import java.util.*;
 import java.io.IOException;
+import java.util.stream.Collectors;
 
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
@@ -46,6 +58,12 @@ public class InvoiceController {
 
     @Resource
     private InvoiceService invoiceService;
+    @Resource
+    private CompanyService companyService;
+    @Resource
+    private InvoiceDetailsMapper invoiceDetailsMapper;
+    @Resource
+    private InvoiceOrdersService invoiceOrdersService;
 
     @GetMapping("/get")
     @Operation(summary = "获得发票")
@@ -185,4 +203,53 @@ public class InvoiceController {
         String result = invoiceService.generateContract(generateContractVO);
         return success("操作成功");
     }
+
+    @PostMapping("/getSigningDate")
+    @Operation(summary = "获取签订日期")
+    public CommonResult<?> getSigningDate(@RequestBody GenerateContractVO generateContractVO) {
+        List<InvoiceDO> list = null;
+        String signingDate = "";
+        list = invoiceService.list(Wrappers.<InvoiceDO>lambdaQuery().in(InvoiceDO::getId,Arrays.asList(generateContractVO.getIds().split(","))).in(InvoiceDO::getStatus, Arrays.asList("0,2".split(","))));
+        if(list ==null || list.size()==0) {
+            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(),"无可生成合同的发票数据");
+        }
+        Map<String, List<InvoiceDO>> invoicesMap = list.stream().collect(Collectors.groupingBy(item -> item.getXfmc() + "-" + item.getGfmc()+ "-" +item.getVsbed()));
+        if(invoicesMap.size()>1){
+            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(),"请选择售达方、公司主体、运输方式一致的发票数据");
+        }
+        for (String key : invoicesMap.keySet()) {
+            List<InvoiceDO> invoiceList = invoicesMap.get(key);
+            if (invoiceList.size() > 0) {
+                InvoiceDO maxInvoice = invoiceList.stream().max(Comparator.comparing(InvoiceDO::getKprq)).get();
+                InvoiceDO minInvoice = invoiceList.stream().min(Comparator.comparing(InvoiceDO::getKprq)).get();
+                CompanyDO company = companyService.getOne(Wrappers.<CompanyDO>lambdaQuery().eq(CompanyDO::getCompanyName, maxInvoice.getGfmc()));
+                if (!"3".equals(generateContractVO.getType())) {
+                    List<String> zskpIds = invoiceList.stream().map(InvoiceDO::getZskpId).collect(Collectors.toList());
+                    List<Map<String, Object>> detailsSumList = invoiceDetailsMapper.selectMaps(Wrappers.<InvoiceDetailsDO>query().select("ggxh, hsdj ,sum(hsje) as hsjeTotal ,sum(sl) as slTotal").in("zskp_id", zskpIds).groupBy("ggxh", "hsdj").having("SUM(hsje) <= 0 or SUM(sl) <= 0"));
+                    if (detailsSumList.size() > 0) {
+                        throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "明细数据存在金额或数量统计为负数");
+                    }
+                }
+                if (company != null) {
+                    //公司间签订日期:最早的开票月份的一号
+                        signingDate = minInvoice.getInvoiceMonth() + "-01";
+                } else {
+                    if ("3".equals(generateContractVO.getType())) {
+                        //退货协议订日期:最早的发货单过账日期
+                        List<String> ddSqkpRecordIds = invoiceList.stream().map(InvoiceDO::getDdSqkpRecordId).collect(Collectors.toList());
+                        InvoiceOrdersDO invoiceOrders = invoiceOrdersService.getOne(Wrappers.<InvoiceOrdersDO>lambdaQuery().in(InvoiceOrdersDO::getDdSqkpRecordId, ddSqkpRecordIds).orderByAsc(InvoiceOrdersDO::getWadatLst), false);
+                        if (invoiceOrders == null) {
+                            continue;
+                        }
+                        signingDate = DateUtil.format(invoiceOrders.getWadatLst(), "yyyy-MM-dd");
+                    } else {
+                        //其他:最早的开票日期
+                        signingDate = DateUtil.formatDate(DateUtil.parseDateTime(minInvoice.getKprq()));
+                    }
+                }
+            }
+        }
+        return success(signingDate);
+    }
+
 }

+ 8 - 0
yudao-module-contract/yudao-module-contract-biz/src/main/java/cn/iocoder/yudao/module/contract/controller/admin/invoice/vo/GenerateContractVO.java

@@ -16,4 +16,12 @@ public class GenerateContractVO {
      * 3:批量生成退货协议
      */
     private String type;
+
+
+    /**
+     * 1:手动生成
+     * 2:批量生成
+     * 3:批量生成退货协议
+     */
+    private String signingDate;
 }

+ 2 - 2
yudao-module-contract/yudao-module-contract-biz/src/main/java/cn/iocoder/yudao/module/contract/dal/dataobject/basicData/BasicSupplierDO.java

@@ -31,12 +31,12 @@ public class BasicSupplierDO extends BaseDO {
     /**
      * 供应商名称
      */
-    @JSONField(name="LIFNR")
+    @JSONField(name="NAME")
     private String name;
     /**
      * 供应商编码
      */
-    @JSONField(name="NAME")
+    @JSONField(name="LIFNR")
     private String code;
     /**
      * 创建日期

+ 3 - 3
yudao-module-contract/yudao-module-contract-biz/src/main/java/cn/iocoder/yudao/module/contract/dal/mysql/order/OrderMapper.java

@@ -82,10 +82,10 @@ public interface OrderMapper extends BaseMapperX<OrderDO> {
                 .in(!ObjectUtils.isEmpty(reqVO.getZzhtgklxms()),OrderDO::getZzhtgklxms,  !ObjectUtils.isEmpty(reqVO.getZzhtgklxms()) ?reqVO.getZzhtgklxms().split(","): new Object[]{""})
                 .in(!ObjectUtils.isEmpty(reqVO.getPzinfo()),OrderDO::getAuartt,  !ObjectUtils.isEmpty(reqVO.getPzinfo()) ?reqVO.getPzinfo().split(","): new Object[]{""})
                 .in(!ObjectUtils.isEmpty(reqVO.getBuinfo()),OrderDO::getButxt,  !ObjectUtils.isEmpty(reqVO.getBuinfo()) ?reqVO.getBuinfo().split(","): new Object[]{""})
-                .in(!ObjectUtils.isEmpty(reqVO.getKuinfo()),OrderDO::getKname,  !ObjectUtils.isEmpty(reqVO.getKuinfo()) ?reqVO.getKuinfo().split(","): new Object[]{""})
+//                .in(!ObjectUtils.isEmpty(reqVO.getKuinfo()),OrderDO::getKname,  !ObjectUtils.isEmpty(reqVO.getKuinfo()) ?reqVO.getKuinfo().split(","): new Object[]{""})
 
-                .like(!ObjectUtils.isEmpty(reqVO.getKunnr()) && "1".equals(reqVO.getKunnrType()),OrderDO::getKname, reqVO.getKunnr())
-                .in(!ObjectUtils.isEmpty(reqVO.getKunnr()) && "2".equals(reqVO.getKunnrType()),OrderDO::getKname, !ObjectUtils.isEmpty(reqVO.getKunnr()) ?reqVO.getKunnr().split(","): new Object[]{""})
+                .like(!ObjectUtils.isEmpty(reqVO.getKunnr()) && "1".equals(reqVO.getKunnrType()),OrderDO::getKunnr, reqVO.getKunnr())
+                .in(!ObjectUtils.isEmpty(reqVO.getKunnr()) && "2".equals(reqVO.getKunnrType()),OrderDO::getKunnr, !ObjectUtils.isEmpty(reqVO.getKunnr()) ?reqVO.getKunnr().split(","): new Object[]{""})
 
                 .in(!ObjectUtils.isEmpty(reqVO.getVkinfo()),OrderDO::getVkburt,  !ObjectUtils.isEmpty(reqVO.getVkinfo()) ?reqVO.getVkinfo().split(","): new Object[]{""})
                 .and(!ObjectUtils.isEmpty(reqVO.getVkginfo()),i -> i.like(OrderDO::getVkgrp, reqVO.getVkginfo()).or().like(OrderDO::getVkgrpt, reqVO.getVkginfo()))

+ 16 - 4
yudao-module-contract/yudao-module-contract-biz/src/main/java/cn/iocoder/yudao/module/contract/service/invoice/InvoiceServiceImpl.java

@@ -214,15 +214,19 @@ public class InvoiceServiceImpl extends ServiceImpl<InvoiceMapper, InvoiceDO> im
     @Override
     public String generateContract(GenerateContractVO generateContractVO) {
         List<InvoiceDO> list = null;
+        String signingDate = "";
         if("1".equals(generateContractVO.getType())) {
             //手动生成
             list = list(Wrappers.<InvoiceDO>lambdaQuery().in(InvoiceDO::getId,Arrays.asList(generateContractVO.getIds().split(","))).in(InvoiceDO::getStatus, Arrays.asList("0,2".split(","))));
+            if(StringUtils.isNotBlank(generateContractVO.getSigningDate())){
+                signingDate = generateContractVO.getSigningDate();
+            }
         }else if("2".equals(generateContractVO.getType())) {
             //批量生成
-            list = list(Wrappers.<InvoiceDO>lambdaQuery().in(InvoiceDO::getStatus,Arrays.asList("0,2".split(","))));
+            list = list(Wrappers.<InvoiceDO>lambdaQuery().in(InvoiceDO::getId,Arrays.asList(generateContractVO.getIds().split(","))).in(InvoiceDO::getStatus,Arrays.asList("0,2".split(","))));
         }else if("3".equals(generateContractVO.getType())) {
             //退货批量生成
-            list = list(Wrappers.<InvoiceDO>lambdaQuery().in(InvoiceDO::getStatus,Arrays.asList("0,2".split(","))).le(InvoiceDO::getJshj,"0"));
+            list = list(Wrappers.<InvoiceDO>lambdaQuery().in(InvoiceDO::getId,Arrays.asList(generateContractVO.getIds().split(","))).in(InvoiceDO::getStatus,Arrays.asList("0,2".split(","))).le(InvoiceDO::getJshj,"0"));
         }
         if(list ==null || list.size()==0) {
             throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(),"无可生成合同的发票数据");
@@ -261,7 +265,11 @@ public class InvoiceServiceImpl extends ServiceImpl<InvoiceMapper, InvoiceDO> im
                 if(company!=null){
                     //公司间签订日期:最早的开票月份的一号
                     invoiceContract.setContractType("1");
-                    invoiceContract.setSigningDate((minInvoice.getInvoiceMonth()+"-01"));
+//                    invoiceContract.setSigningDate((minInvoice.getInvoiceMonth()+"-01"));
+                    if(StringUtils.isBlank(signingDate)){
+                        signingDate = minInvoice.getInvoiceMonth()+"-01";
+                    }
+                    invoiceContract.setSigningDate(signingDate);
                 }else{
                     if("3".equals(generateContractVO.getType())) {
                         //退货协议订日期:最早的发货单过账日期
@@ -275,7 +283,11 @@ public class InvoiceServiceImpl extends ServiceImpl<InvoiceMapper, InvoiceDO> im
                     }else{
                         //其他:最早的开票日期
                         invoiceContract.setContractType("2");
-                        invoiceContract.setSigningDate(DateUtil.formatDate(DateUtil.parseDateTime(minInvoice.getKprq())));
+//                        invoiceContract.setSigningDate(DateUtil.formatDate(DateUtil.parseDateTime(minInvoice.getKprq())));
+                        if(StringUtils.isBlank(signingDate)){
+                            signingDate = DateUtil.formatDate(DateUtil.parseDateTime(minInvoice.getKprq()));
+                        }
+                        invoiceContract.setSigningDate(signingDate);
                     }
                 }
                 invoiceContract.setInvoiceMonth(minInvoice.getInvoiceMonth());

+ 134 - 3
yudao-module-contract/yudao-module-contract-biz/src/main/java/cn/iocoder/yudao/module/contract/service/invoiceContract/InvoiceContractServiceImpl.java

@@ -192,6 +192,25 @@ public class InvoiceContractServiceImpl extends ServiceImpl<InvoiceContractMappe
             if(contractTemplate==null){
                 throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(),"合同模板不存在");
             }
+            ContractTemplateDO template1 = null;
+            ContractTemplateDO template2 = null;
+            if("F2".equals(contractTemplate.getContractTypeCode())){
+                //发票购销合同需添加附件
+                template1 = contractTemplateService.getOne(Wrappers.<ContractTemplateDO>lambdaQuery().eq(ContractTemplateDO::getContractTypeCode,"F2-1").eq(ContractTemplateDO::getClientCode,maxInvoice.getClientCode()));
+                if(template1==null){
+                    template1 = contractTemplateService.getOne(Wrappers.<ContractTemplateDO>lambdaQuery().eq(ContractTemplateDO::getContractTypeCode,"F2-1"));
+                }
+                if(template1==null){
+                    throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(),"发票明细附件模板不存在");
+                }
+                template2 = contractTemplateService.getOne(Wrappers.<ContractTemplateDO>lambdaQuery().eq(ContractTemplateDO::getContractTypeCode,"F2-2").eq(ContractTemplateDO::getClientCode,maxInvoice.getClientCode()));
+                if(template2==null){
+                    template2 = contractTemplateService.getOne(Wrappers.<ContractTemplateDO>lambdaQuery().eq(ContractTemplateDO::getContractTypeCode,"F2-2"));
+                }
+                if(template2==null){
+                    throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(),"借贷项附件模板不存在");
+                }
+            }
             invoiceContract.setContractTemplateId(contractTemplate.getId());
             invoiceContract.setContractTemplateName(contractTemplate.getContractName());
 
@@ -221,11 +240,25 @@ public class InvoiceContractServiceImpl extends ServiceImpl<InvoiceContractMappe
             }
             invoiceContract.setFrameworkAgreementId(frameworkAgreementId);
 
+            Map<String,Object> param = buildContractParam(invoiceContract,invoiceDetails,company,clientDO,frameworkAgreementNo,invoiceList);
             String htmlContent = contractTemplate.getContractContent();
             htmlContent = htmlInit(htmlContent);
-            Map<String,Object> param = buildContractParam(invoiceContract,invoiceDetails,company,clientDO,frameworkAgreementNo);
             htmlContent = HtmlToFileConverter.authHtmlToPdf(htmlContent, param);
-            String fileUrl = htmlToFileConverter.htmlToWord(htmlContent,"invoiceContract/"+invoiceContract.getContractNo(),"fpht-");
+            String fileUrl = null;
+            if("F2".equals(contractTemplate.getContractTypeCode())){
+                //销购发票需要拼接附件
+                List<String> htmlContents = new ArrayList<>();
+                htmlContents.add(htmlContent);
+                htmlContents.add(generateAttachmentHtml(template1,param));
+                if(false){
+                    generateAttachmentHtml(template2,param);
+                }
+                fileUrl = htmlToFileConverter.htmlToWord(htmlContents,"invoiceContract/"+invoiceContract.getContractNo(),"fpht-");
+                htmlContent = StringUtils.join(htmlContents,"<div style='break-after: page;'></div><div class='page-break'>")+"</div>";
+            }else{
+                fileUrl = htmlToFileConverter.htmlToWord(htmlContent,"invoiceContract/"+invoiceContract.getContractNo(),"fpht-");
+            }
+
             invoiceContract.setGeneratedTime(LocalDateTime.now());
             invoiceContract.setContractHtml(htmlContent);
             invoiceContract.setContractFileUrl(fileUrl);
@@ -242,6 +275,22 @@ public class InvoiceContractServiceImpl extends ServiceImpl<InvoiceContractMappe
         }
     }
 
+    private String generateAttachmentHtml(ContractTemplateDO template,Map<String,Object> param)throws Exception {
+        if("F2-1".equals(template.getContractTypeCode())){
+            String htmlContent = "";
+            htmlContent = invoiceListHtmlInit(template.getContractContent());
+            htmlContent = HtmlToFileConverter.authHtmlToPdf(htmlContent, param);
+            return htmlContent;
+        }
+        if("F2-2".equals(template.getContractTypeCode())){
+            String htmlContent = "";
+            htmlContent = loanItemHtmlInit(template.getContractContent());
+            htmlContent = HtmlToFileConverter.authHtmlToPdf(htmlContent, param);
+            return htmlContent;
+        }
+        return null;
+    }
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void cancellation(InvoiceContractDO invoiceContract,List<InvoiceDO> invoiceList) {
@@ -255,7 +304,7 @@ public class InvoiceContractServiceImpl extends ServiceImpl<InvoiceContractMappe
 
     }
 
-    private Map<String, Object> buildContractParam(InvoiceContractDO invoiceContract, Map<String, List<InvoiceDetailsDO>> invoiceDetails, CompanyDO companyDO, ClientDO clientDO,String frameworkAgreementNo) {
+    private Map<String, Object> buildContractParam(InvoiceContractDO invoiceContract, Map<String, List<InvoiceDetailsDO>> invoiceDetails, CompanyDO companyDO, ClientDO clientDO,String frameworkAgreementNo,List<InvoiceDO> invoiceList) {
         Map<String,Object> param = new HashMap<>();
         //订单信息
         param.put("购方名称", StringUtils.nvl(invoiceContract.getGfmc(), ""));
@@ -347,6 +396,21 @@ public class InvoiceContractServiceImpl extends ServiceImpl<InvoiceContractMappe
         }
         param.put("invoiceDetails",details);
 
+
+        List<Map<String,Object>> invoices = new ArrayList<>();
+        for(int i=0;i<invoiceList.size();i++){
+            InvoiceDO invoiceDO = invoiceList.get(i);
+            Map<String,Object> data = new HashMap<>();
+            data.put("序号",i+1);
+            data.put("明细合同编号", StringUtils.nvl(invoiceDO.getDdh(),""));
+            data.put("明细发票号码", StringUtils.nvl(invoiceDO.getFphm(),""));
+            data.put("明细金额", StringUtils.nvl(MoneyUtil.toSeparator(invoiceDO.getJshj()),""));
+            data.put("明细开票日期", StringUtils.nvl(invoiceDO.getKprq(),""));
+            invoices.add(data);
+        }
+        param.put("invoiceList",invoices);
+
+
         //产品合计
         param.put("数量合计",MoneyUtil.toSeparator(quantityTotal.toString()));
         param.put("不含税总金额合计", StringUtils.nvl(MoneyUtil.toSeparator(noTaxAmountSum.toString()), ""));
@@ -429,6 +493,73 @@ public class InvoiceContractServiceImpl extends ServiceImpl<InvoiceContractMappe
         return htmlContent;
     }
 
+
+    private String invoiceListHtmlInit(String htmlContent) {
+        htmlContent= htmlContent.replaceAll("\\$\\{序号}","\\$\\{invoice.序号}");
+        htmlContent= htmlContent.replaceAll("\\$\\{明细合同编号}","\\$\\{invoice.明细合同编号}");
+        htmlContent= htmlContent.replaceAll("\\$\\{明细发票号码}","\\$\\{invoice.明细发票号码}");
+        htmlContent= htmlContent.replaceAll("\\$\\{明细金额}","\\$\\{invoice.明细金额}");
+        htmlContent= htmlContent.replaceAll("\\$\\{明细开票日期}","\\$\\{invoice.明细开票日期}");
+
+
+//        htmlContent = addWatermark(htmlContent);
+        Document doc = Jsoup.parse(htmlContent);
+        Elements tdElements =  doc.select("td");
+        for (Element cell : tdElements) {
+            String text = cell.text(); // 获取td元素及其所有子元素的文本内容
+            if (text.startsWith("${invoice.")) {
+                Element tr = cell.parent(); // 获取单元格的父元素
+                if (tr.tagName().equals("tr")) { // 确保父元素是tr
+                    Element trr = tr.parent(); // 获取单元格的父元素
+                    if(!trr.tagName().equals("list")) {
+                        // 创建<#list></#list>元素
+                        tr.wrap("<list>");
+                    }
+                }
+            }
+        }
+
+        htmlContent = doc.html();
+        htmlContent = htmlContent.replaceAll("<list>","<#list invoiceList as invoice>");
+        htmlContent = htmlContent.replaceAll("</list>","</#list>");
+        return htmlContent;
+    }
+
+
+    private String loanItemHtmlInit(String htmlContent) {
+        htmlContent= htmlContent.replaceAll("\\$\\{序号}","\\$\\{item.序号}");
+        htmlContent= htmlContent.replaceAll("\\$\\{借贷项发票号码}","\\$\\{item.借贷项发票号码}");
+        htmlContent= htmlContent.replaceAll("\\$\\{借贷项金额}","\\$\\{item.借贷项金额}");
+        htmlContent= htmlContent.replaceAll("\\$\\{借贷项类型}","\\$\\{item.借贷项类型}");
+
+//        htmlContent= htmlContent.replaceAll("\\$\\{数量合计}","\\$\\{invoiceDetail.数量合计}");
+//        htmlContent= htmlContent.replaceAll("\\$\\{不含税总金额合计}","\\$\\{invoiceDetail.不含税总金额合计}");
+//        htmlContent= htmlContent.replaceAll("\\$\\{含税金额合计}","\\$\\{invoiceDetail.含税金额合计}");
+//        htmlContent= htmlContent.replaceAll("\\$\\{合计金额大写}","\\$\\{invoiceDetail.合计金额大写}");
+
+//        htmlContent = addWatermark(htmlContent);
+        Document doc = Jsoup.parse(htmlContent);
+        Elements tdElements =  doc.select("td");
+        for (Element cell : tdElements) {
+            String text = cell.text(); // 获取td元素及其所有子元素的文本内容
+            if (text.startsWith("${item.")) {
+                Element tr = cell.parent(); // 获取单元格的父元素
+                if (tr.tagName().equals("tr")) { // 确保父元素是tr
+                    Element trr = tr.parent(); // 获取单元格的父元素
+                    if(!trr.tagName().equals("list")) {
+                        // 创建<#list></#list>元素
+                        tr.wrap("<list>");
+                    }
+                }
+            }
+        }
+
+        htmlContent = doc.html();
+        htmlContent = htmlContent.replaceAll("<list>","<#list loanItem as item>");
+        htmlContent = htmlContent.replaceAll("</list>","</#list>");
+        return htmlContent;
+    }
+
     public static String sequenceCode(Integer maxNum, Long count) {  // 如生成001这种,maxNum为1000  0001的话maxNum则为10000,count则是我们从数据库中查询的总数
 
         String strNum = String.valueOf(maxNum + count);