ソースを参照

1.机器设备-设备融资项目报告word生成开发
2.新增DateToChinese工具类,将Date类型日期或String字符串日期转换为汉字字符串日期

GouGengquan 7 ヶ月 前
コミット
a13ac48f05

+ 1 - 1
biz-base/src/test/java/com/dayou/WordSimpleTests.java

@@ -176,7 +176,7 @@ public class WordSimpleTests {
         // 需要插入的word文件
         Document subDoc = new Document("E:\\test\\word\\5_main_output.doc");
 
-        mainDoc = AsposeWordUtil.insertDocumentAfterBookMark(mainDoc, subDoc, bookmark, false, true);
+        mainDoc = AsposeWordUtil.insertDocumentAfterBookMark(mainDoc, subDoc, bookmark, false, true, false);
         // 保存文件
         mainDoc.save("E:\\test\\word\\2_framework_output.doc");
     }

+ 14 - 5
common/src/main/java/com/dayou/utils/AsposeWordUtil.java

@@ -262,14 +262,23 @@ public class AsposeWordUtil {
                 if (bm != null) {
                     // 移动光标到书签
                     mainDocBuilder.moveToBookmark(bookmark, true, false);
-                    // 在文档中插入段落分隔符
-                    if (writeln) {
+                    // 判断是否需要插入段落分隔符
+                    if (writeln) { // 插入分隔符会在分隔符后面插入word
+                        // 移动光标到书签
+                        mainDocBuilder.moveToBookmark(bookmark, true, false);
+                        // 在文档中插入段落分隔符
                         mainDocBuilder.writeln();
+                        //获取到插入的位置
+                        Node insertAfterNode = mainDocBuilder.getCurrentParagraph().getPreviousSibling();
+                        insertDocumentAfterNode(insertAfterNode, mainDoc, tobeInserted);
+                    }else { // 不插入分隔符会直接获取书签的段落然后插入word
+                        //定位到书签
+                        Bookmark bookmarkData = mainDoc.getRange().getBookmarks().get(bookmark);
+                        //获取到插入的位置
+                        Node insertAfterNode = bookmarkData.getBookmarkStart().getParentNode();
+                        insertDocumentAfterNode(insertAfterNode, mainDoc, tobeInserted);
                     }
-                    //获取到插入的位置
-                    Node insertAfterNode = mainDocBuilder.getCurrentParagraph().getPreviousSibling();
 
-                    insertDocumentAfterNode(insertAfterNode, mainDoc, tobeInserted);
                 }
             } else { // 文档末尾拼接
                 appendDoc(mainDoc, tobeInserted, true);

+ 143 - 0
common/src/main/java/com/dayou/utils/DateToChinese.java

@@ -0,0 +1,143 @@
+package com.dayou.utils;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class DateToChinese {
+
+    /**
+     * 将Date转换为汉字
+     * @param date 时间
+     * @return 汉字年月日
+     */
+    public static String dateConvertChinese(Date date) {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-M-d");
+        String format = sdf.format(date);
+        String[] split = format.split("-");
+        String year = split[0];
+        String month = split[1];
+        String day = split[2];
+        String strYear = getStrYear(year);
+        String strMonth = getStrMonth(month);
+        String strDay = getStrDay(day);
+
+        return strYear + "年" + strMonth + "月" + strDay + "号";
+    }
+
+    /**
+     * 将字符串日期转换为汉字
+     * @param dateStr 时间(如:2024年12月11日)
+     * @return 汉字年月日(如:二〇二四年十二月十三号)
+     */
+    public static String dateStrConvertChinese(String dateStr) {
+        String[] parts = dateStr.split("[年月日]");
+        String year = parts[0];
+        String month = parts[1];
+        String day = parts[2];
+        String strYear = getStrYear(year);
+        String strMonth = getStrMonth(month);
+        String strDay = getStrDay(day);
+
+        return strYear + "年" + strMonth + "月" + strDay + "号";
+    }
+
+    /**
+     * @param day 数字日 13
+     * @return 汉字日 13==>十三
+     */
+    public static String getStrDay(String day) {
+        int dayLength = day.length();
+        String strDay = "";
+        if (dayLength < 2) {
+            strDay = numToStr(day);
+            return strDay;
+        } else {
+            if (day.startsWith("1")) {
+                if (day.equals("10")) {
+                    return "十";
+                } else {
+                    String substring = day.substring(1);
+                    strDay = "十" + numToStr(substring);
+                    return strDay;
+                }
+            } else if (day.startsWith("2")) {
+                if (day.equals("20")) {
+                    return "二十";
+                } else {
+                    String substring = day.substring(1);
+                    strDay = "二十" + numToStr(substring);
+                    return strDay;
+                }
+            } else if (day.startsWith("3")) {
+                if (day.equals("30")) {
+                    return "三十";
+                } else {
+                    String substring = day.substring(1);
+                    strDay = "三十" + numToStr(substring);
+                    return strDay;
+                }
+            }
+        }
+        return "";
+    }
+
+
+    /**
+     * @param month 数字月 7
+     * @return 中文月 7==>七
+     */
+    public static String getStrMonth(String month) {
+        return numToStr(month);
+    }
+
+    /**
+     * @param year 数字年 2024
+     * @return 汉字年 二零二四
+     */
+    public static String getStrYear(String year) {
+        int length = year.length();
+        StringBuilder strYear = new StringBuilder();
+        for (int i = 0; i < length; i++) {
+            String substring = year.substring(i, i + 1);
+            strYear.append(numToStr(substring));
+        }
+        return strYear.toString();
+    }
+
+    /**
+     * @param nun 0~9 ==>〇~九
+     * @return
+     */
+    public static String numToStr(String nun) {
+        switch (nun) {
+            case "0":
+                return "〇";
+            case "1":
+                return "一";
+            case "2":
+                return "二";
+            case "3":
+                return "三";
+            case "4":
+                return "四";
+            case "5":
+                return "五";
+            case "6":
+                return "六";
+            case "7":
+                return "七";
+            case "8":
+                return "八";
+            case "9":
+                return "九";
+            case "10":
+                return "十";
+            case "11":
+                return "十一";
+            case "12":
+                return "十二";
+        }
+        return "";
+    }
+
+}

+ 5 - 0
domain/src/main/java/com/dayou/bo/EqptReportFillBO.java

@@ -14,6 +14,11 @@ public class EqptReportFillBO {
     private String productionNo;
 
     /**
+     * 中文日期
+     */
+    private String chineseReportDate;
+
+    /**
      * 账面原值
      */
     private BigDecimal bookOriginalValue;

+ 10 - 0
domain/src/main/java/com/dayou/dto/report/equipment/EqptReportBaseInfoDTO.java

@@ -147,6 +147,16 @@ public class EqptReportBaseInfoDTO {
     public static class PropertyOwnerInfo {
 
         /**
+         * 序号
+         */
+        private Integer sort;
+
+        /**
+         * 序号(大写汉字)
+         */
+        private String sortUppercase;
+
+        /**
          * 公司名称
          */
         private String ownerCompanyName;

+ 2 - 0
domain/src/main/java/com/dayou/enums/EqptReportTmplCode.java

@@ -5,7 +5,9 @@ public enum EqptReportTmplCode {
     MAIN("MAIN", "设备融资项目报告-框架-主模板"),
     COVER("COVER", "设备融资项目报告-封面-段落模板"),
     CATALOGUE("CATALOGUE", "设备融资项目报告-目录-段落模板"),
+    ATTACHMENTS("ATTACHMENTS", "设备融资项目报告-附件-段落模板"),
     DETAIL("DETAIL", "设备融资项目报告-正文-段落模板"),
+    DIGEST("DIGEST", "设备融资项目报告-摘要-段落模板"),
     CONSIGNOR("CONSIGNOR", "设备融资项目报告-委托人概况-段落模板"),
     PROPERTY_OWNER("PROPERTY_OWNER", "设备融资项目报告-产权持有人概况-段落模板");
 

+ 154 - 18
service/src/main/java/com/dayou/service/impl/AssetsReportServiceImpl.java

@@ -4,21 +4,25 @@ import cn.dev33.satoken.stp.StpUtil;
 import cn.hutool.core.util.ObjectUtil;
 import com.aspose.words.Document;
 import com.aspose.words.DocumentBuilder;
+import com.aspose.words.ImportFormatMode;
 import com.aspose.words.Paragraph;
 import com.dayou.bo.EqptReportFillBO;
 import com.dayou.config.FileNetConfig;
 import com.dayou.dto.report.ReportBaseInfoDTO;
 import com.dayou.dto.report.equipment.EqptReportBaseInfoDTO;
 import com.dayou.entity.AssetsReport;
+import com.dayou.entity.TmplAssetReport;
 import com.dayou.entity.TmplAssetReportSection;
 import com.dayou.enums.EqptReportTmplCode;
 import com.dayou.mapper.AssetsReportMapper;
+import com.dayou.mapper.TmplAssetReportMapper;
 import com.dayou.mapper.TmplAssetReportSectionMapper;
 import com.dayou.service.AssetsReportService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.dayou.utils.ArabicToChineseUtil;
 import com.dayou.utils.AsposeWordUtil;
 import com.dayou.utils.DataUtil;
+import com.dayou.utils.DateToChinese;
 import com.dayou.vo.AssetsReportVO;
 import com.dayou.vo.report.AssetsReportProgressVO;
 import com.fasterxml.jackson.core.JsonProcessingException;
@@ -33,9 +37,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
+import java.io.*;
 import java.math.RoundingMode;
 import java.nio.file.Files;
 import java.nio.file.Paths;
@@ -62,6 +64,9 @@ public class AssetsReportServiceImpl extends ServiceImpl<AssetsReportMapper, Ass
     private AssetsReportMapper assetsReportMapper;
 
     @Autowired
+    private TmplAssetReportMapper tmplAssetReportMapper;
+
+    @Autowired
     private TmplAssetReportSectionMapper reportSectionMapper;
 
     @Autowired
@@ -162,6 +167,12 @@ public class AssetsReportServiceImpl extends ServiceImpl<AssetsReportMapper, Ass
         eqptReportFillBO.setOwnerCompanyName(eqptReportFillBO.getEqptReportBaseInfo().getPropertyOwnerInfos().stream() // 将集合转换为流
                 .map(EqptReportBaseInfoDTO.PropertyOwnerInfo::getOwnerCompanyName) // 提取每个对象的ownerCompanyName属性
                 .collect(Collectors.joining("、")));
+        // 将评估基准日只截取年月,并设置为开始评估工作年月
+        String[] parts = eqptReportFillBO.getEqptReportBaseInfo().getValuationBasisDate().split("日");
+        String yearMonth = parts[0];
+        eqptReportFillBO.setStartWorkMonth(yearMonth);
+        // 将评估报告日转换为中文并设置到中文评估报告日中
+        eqptReportFillBO.setChineseReportDate(DateToChinese.dateStrConvertChinese(eqptReportFillBO.getEqptReportBaseInfo().getReportDate()));
 
         // 第一步:设置封面
         // 获取封面模板
@@ -174,7 +185,7 @@ public class AssetsReportServiceImpl extends ServiceImpl<AssetsReportMapper, Ass
         // 读取模板文件
         byte[] coverTmplByte = Files.readAllBytes(Paths.get(coverTmplPath));
         // 获取填充数据后的文件
-        byte[] resultCoverByte = AsposeWordUtil.fillWordDataByDomain(coverTmplByte, eqptReportFillBO);
+        byte[] resultCoverByte = AsposeWordUtil.fillWordDataByMap(coverTmplByte, DataUtil.objToMap(eqptReportFillBO));
 
         // 处理该二进制文件并保存
         File resultFile = new File(coverPath);
@@ -182,7 +193,27 @@ public class AssetsReportServiceImpl extends ServiceImpl<AssetsReportMapper, Ass
         fos.write(resultCoverByte);
         fos.close();
 
-        // 第二步:设置正文内容
+        // 第二步:设置摘要内容
+        // 获取正文
+        TmplAssetReportSection digestTmpl = reportSectionMapper.getTmplByCode(DIGEST.getCode());
+        // 封面生成后文件位置
+        String digestPath = fileNetConfig.getBaseDir() + fileNetConfig.getAssetOutputReportPath() + System.currentTimeMillis() + "_DIGEST.docx";
+        // 封面模板文件位置
+        String digestTmplPath = fileNetConfig.getBaseDir() + digestTmpl.getSectionFileUrl() + digestTmpl.getSectionFileName();
+
+        // 读取模板文件
+        byte[] digestTmplByte = Files.readAllBytes(Paths.get(digestTmplPath));
+        // 获取填充数据后的文件
+        byte[] resultdigestByte = AsposeWordUtil.fillWordDataByMap(digestTmplByte, DataUtil.objToMap(eqptReportFillBO));
+
+        // 处理该二进制文件并保存
+        File digestFile = new File(digestPath);
+        FileOutputStream digestOs = new FileOutputStream(digestFile);
+        digestOs.write(resultdigestByte);
+        digestOs.close();
+        Document digestDoc = new Document(digestPath);
+
+        // 第三步:设置正文内容
         // 获取正文
         TmplAssetReportSection detailTmpl = reportSectionMapper.getTmplByCode(DETAIL.getCode());
         // 封面生成后文件位置
@@ -191,17 +222,20 @@ public class AssetsReportServiceImpl extends ServiceImpl<AssetsReportMapper, Ass
         String detailTmplPath = fileNetConfig.getBaseDir() + detailTmpl.getSectionFileUrl() + detailTmpl.getSectionFileName();
 
         // 读取模板文件
-        byte[] mainTmplByte = Files.readAllBytes(Paths.get(detailTmplPath));
+        byte[] detailTmplByte = Files.readAllBytes(Paths.get(detailTmplPath));
         // 获取填充数据后的文件
-        byte[] resultMainByte = AsposeWordUtil.fillWordDataByMap(mainTmplByte, DataUtil.objToMap(eqptReportFillBO));
+        byte[] resultDetailByte = AsposeWordUtil.fillWordDataByMap(detailTmplByte, DataUtil.objToMap(eqptReportFillBO));
 
         // 处理该二进制文件并保存
         File detailFile = new File(detailPath);
         FileOutputStream detailOs = new FileOutputStream(detailFile);
-        detailOs.write(resultMainByte);
+        detailOs.write(resultDetailByte);
         detailOs.close();
 
-        // 第三步:设置委托人概况
+        // 将正文读取出来
+        Document detailDoc = new Document(detailPath);
+
+        // 第四步:设置委托人概况
         // 获取委托人概况模板
         TmplAssetReportSection consignorTmpl = reportSectionMapper.getTmplByCode(CONSIGNOR.getCode());
         // 委托人概况生成后文件位置
@@ -209,11 +243,10 @@ public class AssetsReportServiceImpl extends ServiceImpl<AssetsReportMapper, Ass
         // 委托人概况模板文件位置
         String consignorTmplPath = fileNetConfig.getBaseDir() + consignorTmpl.getSectionFileUrl() + consignorTmpl.getSectionFileName();
 
-        Document detailDoc = new Document(detailPath);
-        for (int i = 0; i < eqptReportFillBO.getEqptReportBaseInfo().getConsignorInfos().size() ; i++) {
-            EqptReportBaseInfoDTO.ConsignorInfo consignorInfo = eqptReportFillBO.getEqptReportBaseInfo().getConsignorInfos().get(i);
-            consignorInfo.setSort(i + 1);
-            consignorInfo.setSortUppercase(ArabicToChineseUtil.int2chineseNum(i + 1));
+        for (int i = eqptReportFillBO.getEqptReportBaseInfo().getConsignorInfos().size(); i > 0; i--) {
+            EqptReportBaseInfoDTO.ConsignorInfo consignorInfo = eqptReportFillBO.getEqptReportBaseInfo().getConsignorInfos().get(i -1);
+            consignorInfo.setSort(i);
+            consignorInfo.setSortUppercase(ArabicToChineseUtil.int2chineseNum(i));
             // 读取模板文件
             byte[] consignorTmplByte = Files.readAllBytes(Paths.get(consignorTmplPath));
             // 获取填充数据后的文件
@@ -228,16 +261,119 @@ public class AssetsReportServiceImpl extends ServiceImpl<AssetsReportMapper, Ass
             detailDoc = AsposeWordUtil.insertDocumentAfterBookMark(detailDoc, consignorDoc, "insertConsignor", false, false);
         }
 
-        DocumentBuilder builder = new DocumentBuilder(detailDoc);
+        // 第五步:设置产权持有人概况
+        // 获取产权持有人概况模板
+        TmplAssetReportSection ownerTmpl = reportSectionMapper.getTmplByCode(PROPERTY_OWNER.getCode());
+        // 产权持有人概况生成后文件位置
+        String ownerPath = fileNetConfig.getBaseDir() + fileNetConfig.getAssetOutputReportPath() + System.currentTimeMillis() + "_PROPERTY_OWNER.docx";
+        // 产权持有人概况模板文件位置
+        String ownerTmplPath = fileNetConfig.getBaseDir() + ownerTmpl.getSectionFileUrl() + ownerTmpl.getSectionFileName();
+
+        for (int i = eqptReportFillBO.getEqptReportBaseInfo().getPropertyOwnerInfos().size(); i > 0; i--) {
+            EqptReportBaseInfoDTO.PropertyOwnerInfo propertyOwnerInfo = eqptReportFillBO.getEqptReportBaseInfo().getPropertyOwnerInfos().get(i - 1);
+            propertyOwnerInfo.setSort(i);
+            propertyOwnerInfo.setSortUppercase(ArabicToChineseUtil.int2chineseNum(i));
+            // 读取模板文件
+            byte[] consignorTmplByte = Files.readAllBytes(Paths.get(ownerTmplPath));
+            // 获取填充数据后的文件
+            byte[] resultConsignorByte = AsposeWordUtil.fillWordDataByDomain(consignorTmplByte, propertyOwnerInfo);
+            // 处理该二进制文件并保存
+            File ownerFile = new File(ownerPath);
+            FileOutputStream consignorOs = new FileOutputStream(ownerFile);
+            consignorOs.write(resultConsignorByte);
+            consignorOs.close();
 
+            Document ownerDoc = new Document(ownerPath);
+            detailDoc = AsposeWordUtil.insertDocumentAfterBookMark(detailDoc, ownerDoc, "insertPropertyOwner", false, false);
+        }
+
+        // 删除两个书签所在的空白行
+        DocumentBuilder builder = new DocumentBuilder(detailDoc);
         builder.moveToBookmark("insertConsignor");
+        // 获取当前光标所在的段落
+        Paragraph currentParagraph1 = builder.getCurrentParagraph();
+        currentParagraph1.remove();
+        builder.moveToBookmark("insertPropertyOwner");
+        // 获取当前光标所在的段落
+        Paragraph currentParagraph2 = builder.getCurrentParagraph();
+        currentParagraph2.remove();
 
+        // 保存正文文件
+        detailDoc.save(detailPath);
+
+        // 第六步:设置主体框架
+        // 获取框架模板
+        TmplAssetReport mainTmpl = tmplAssetReportMapper.getTmplByCode(MAIN.getCode());
+        // 框架生成后文件位置
+        String mainPath = fileNetConfig.getBaseDir() + fileNetConfig.getAssetOutputReportPath() + System.currentTimeMillis() + "_MAIN.docx";
+        // 框架模板文件位置
+        String mainTmplPath = fileNetConfig.getBaseDir() + mainTmpl.getFileUrl() + mainTmpl.getFileName();
+
+        // 读取模板文件
+        byte[] mainTmplByte = Files.readAllBytes(Paths.get(mainTmplPath));
+        // 获取填充数据后的文件
+        byte[] resultMainByte = AsposeWordUtil.fillWordDataByMap(mainTmplByte, DataUtil.objToMap(eqptReportFillBO));
+        InputStream mainIs = new ByteArrayInputStream(resultMainByte);
+        // 将框架读取出来
+        Document mainDoc = new Document(mainIs);
+        // 将摘要插入到框架
+        AsposeWordUtil.insertDocumentAfterBookMark(mainDoc, digestDoc, "insertDigest", false, false);
+        // 将正文插入到框架
+        AsposeWordUtil.insertDocumentAfterBookMark(mainDoc, detailDoc, "insertDetail", false, false);
+
+        // 获取目录模板
+        TmplAssetReportSection catalogueTmpl = reportSectionMapper.getTmplByCode(CATALOGUE.getCode());
+        // 目录模板文件位置
+        String catalogueTmplPath = fileNetConfig.getBaseDir() + catalogueTmpl.getSectionFileUrl() + catalogueTmpl.getSectionFileName();
+        // 将框架读取出来
+        Document catalogueDoc = new Document(catalogueTmplPath);
+
+        // 获取附件模板
+        TmplAssetReportSection attachmentsTmpl = reportSectionMapper.getTmplByCode(ATTACHMENTS.getCode());
+        // 附件模板文件位置
+        String attachmentsPath = fileNetConfig.getBaseDir() + attachmentsTmpl.getSectionFileUrl() + attachmentsTmpl.getSectionFileName();
+        // 读取模板文件
+        byte[] attachmentsTmplByte = Files.readAllBytes(Paths.get(attachmentsPath));
+        // 获取填充数据后的文件
+        byte[] resultAttachmentsByte = AsposeWordUtil.fillWordDataByMap(attachmentsTmplByte, DataUtil.objToMap(eqptReportFillBO));
+        InputStream attachmentsIs = new ByteArrayInputStream(resultAttachmentsByte);
+        // 将附件读取出来
+        Document attachmentsDoc = new Document(attachmentsIs);
+        // 将附件插入到目录
+        AsposeWordUtil.insertDocumentAfterBookMark(catalogueDoc, attachmentsDoc, "insertAttachments", false, false);
+
+        // 将目录插入到框架
+        AsposeWordUtil.insertDocumentAfterBookMark(mainDoc, catalogueDoc, "insertCatalogue", false, false);
+
+        // 删除书签所在的空白行
+        DocumentBuilder mainBuilder = new DocumentBuilder(mainDoc);
+
+        mainBuilder.moveToBookmark("insertDetail");
         // 获取当前光标所在的段落
-        Paragraph currentParagraph = builder.getCurrentParagraph();
+        Paragraph mainCurrentParagraph1 = mainBuilder.getCurrentParagraph();
+        mainCurrentParagraph1.remove();
 
-        currentParagraph.remove();
+        mainBuilder.moveToBookmark("insertDigest");
+        // 获取当前光标所在的段落
+        Paragraph mainCurrentParagraph2 = mainBuilder.getCurrentParagraph();
+        mainCurrentParagraph2.remove();
 
-        detailDoc.save(detailPath);
+        mainBuilder.moveToBookmark("insertCatalogue");
+        // 获取当前光标所在的段落
+        Paragraph mainCurrentParagraph3 = mainBuilder.getCurrentParagraph();
+        mainCurrentParagraph3.remove();
+
+        mainBuilder.moveToBookmark("insertAttachments");
+        // 获取当前光标所在的段落
+        Paragraph mainCurrentParagraph4 = mainBuilder.getCurrentParagraph();
+        mainCurrentParagraph4.remove();
+
+        // 将封面和文档进行拼接
+        Document coverDoc = new Document(coverPath);
+        coverDoc.appendDocument(mainDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING);
+        // 更新目录页码
+        AsposeWordUtil.updateCatalogueLink(coverDoc);
+        coverDoc.save(mainPath);
 
         return null;
     }