Parcourir la source

1.债权分析报告生成调整

GouGengquan il y a 3 mois
Parent
commit
d37fe6ccdc

+ 1 - 1
biz-base/src/main/java/com/dayou/controller/AssetsReportController.java

@@ -26,7 +26,7 @@ import java.util.List;
 @RestController
 @RequestMapping("assetsReport")
 @Slf4j
-@SaCheckLogin
+//@SaCheckLogin
 @CrossOrigin
 public class AssetsReportController {
 

Fichier diff supprimé car celui-ci est trop grand
+ 1 - 1
biz-base/src/test/java/com/dayou/DynamicGenTableWordTest.java


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

@@ -57,19 +57,19 @@ public class WordSimpleTests {
     @Builder
     public static class SimpleWordTableData {
 
-        @WordTableColumn(name = "id")
+        @WordTableColumn(name = "id", fontName = "华文细黑", fontSize = 5.5, titleBold = true, titleFontSize = 8)
         private String id;
 
-        @WordTableColumn(name = "担保人")
+        @WordTableColumn(name = "担保人", fontName = "华文细黑", fontSize = 8, titleBold = true)
         private String pledger;
 
-        @WordTableColumn(name = "合同编号")
+        @WordTableColumn(name = "合同编号", fontName = "华文细黑", fontSize = 8, titleBold = true)
         private String contractNum;
 
-        @WordTableColumn(name = "担保方式")
+        @WordTableColumn(name = "担保方式", fontName = "华文细黑", fontSize = 8, titleBold = true)
         private String guarantyStyle;
 
-        @WordTableColumn(name = "金额")
+        @WordTableColumn(name = "金额", fontName = "华文细黑", fontSize = 8, titleBold = true)
         private String amount;
     }
 
@@ -214,8 +214,21 @@ public class WordSimpleTests {
         SimpleWordTableData data2 = SimpleWordTableData.builder().id("2").pledger("李四").contractNum("合同呜呼呜呼呜呼芜湖").guarantyStyle("抵押").amount("200028万").build();
         List<SimpleWordTableData> contractList = Arrays.asList(data1, data2);
 
-        AsposeWordUtil.createTable(doc, SimpleWordTableData.class, contractList, "table");
-        doc.save("E:\\test\\word\\createTable.doc");
+//        AsposeWordUtil.createTable(doc, SimpleWordTableData.class, contractList, "table");
+
+        DocumentBuilder builder = new DocumentBuilder(doc);
+        int tableIndex=0;
+        //移动至第二行第一列
+        builder.moveToCell(tableIndex,1,0,0);
+        builder.getCellFormat().setVerticalMerge(CellMerge.FIRST);//合并的第一个单元格 保留的值是第一个单元格的值
+        //移动至第三行第一列
+//        builder.moveToCell(tableIndex, 10, 0,0);
+//        builder.getCellFormat().setVerticalMerge(CellMerge.PREVIOUS);//被合并的单元格
+        for(int i = 2; i < 55; i++ ) {
+            builder.moveToCell(0, i, 0, 0);
+            builder.getCellFormat().setVerticalMerge(CellMerge.PREVIOUS);
+        }
+        doc.save("E:\\test\\word\\createTable-test.doc");
     }
 
     /**

+ 106 - 10
common/src/main/java/com/dayou/utils/AsposeWordUtil.java

@@ -376,14 +376,15 @@ public class AsposeWordUtil {
 
     /**
      * 向书签位置插入表格
-     * @param doc
-     * @param clazz
-     * @param list
-     * @param bookmark
+     * @param doc 文档
+     * @param clazz 类
+     * @param list 集合
+     * @param bookmark 书签
+     * @param autoWidth 自动调整列宽
      * @return
      * @throws Exception
      */
-    public static Document createTable(Document doc, Class<?> clazz, List<?> list, String bookmark) throws Exception {
+    public static Document createTable(Document doc, Class<?> clazz, List<?> list, String bookmark, boolean autoWidth) throws Exception {
         // Aspose文档构造器
         DocumentBuilder builder = new DocumentBuilder(doc);
         builder.moveToBookmark(bookmark, true, false);
@@ -401,6 +402,85 @@ public class AsposeWordUtil {
                 // 检查isCreate属性是否为true
                 if (annotation.isCreate()) {
                     builder.insertCell();
+                    builder.getCellFormat().setVerticalAlignment(annotation.cellVerticalAlignment());
+                    builder.getCellFormat().setWidth(annotation.cellWidth());
+                    ParagraphFormat paragraphFormat = builder.getParagraphFormat();
+                    paragraphFormat.setAlignment(annotation.paragraphAlignment());
+                    paragraphFormat.setFirstLineIndent(annotation.firstLineIndent());
+                    paragraphFormat.setLineSpacing(annotation.lineSpacing());
+                    paragraphFormat.setLineSpacingRule(annotation.lineSpacingRule());
+                    builder.getFont().setName(annotation.fontName());
+                    builder.getFont().setBold(annotation.titleBold());
+                    builder.getFont().setSize(annotation.titleFontSize());
+                    builder.write(annotation.name());
+                }
+            }
+        }
+        // 结束行
+        builder.endRow();
+
+        // 创建内容行
+        for (Object obj : list){
+            for (Field field : fields) {
+                // 检查字段是否有自定义注解
+                if (field.isAnnotationPresent(WordTableColumn.class)) {
+                    // 获取注解实例
+                    WordTableColumn annotation = field.getAnnotation(WordTableColumn.class);
+                    // 检查isCreate属性是否为true
+                    if (annotation.isCreate()) {
+                        field.setAccessible(true);
+                        builder.insertCell();
+                        builder.getCellFormat().setVerticalAlignment(annotation.cellVerticalAlignment());
+                        builder.getCellFormat().setWidth(annotation.cellWidth());
+                        ParagraphFormat paragraphFormat = builder.getParagraphFormat();
+                        paragraphFormat.setAlignment(annotation.paragraphAlignment());
+                        paragraphFormat.setFirstLineIndent(annotation.firstLineIndent());
+                        paragraphFormat.setLineSpacing(annotation.lineSpacing());
+                        paragraphFormat.setLineSpacingRule(annotation.lineSpacingRule());
+                        builder.getFont().setName(annotation.fontName());
+                        builder.getFont().setBold(annotation.bold());
+                        builder.getFont().setSize(annotation.fontSize());
+                        builder.write((String) field.get(obj));
+                    }
+                }
+            }
+            // 结束行
+            builder.endRow();
+        }
+
+        // 自动调整列宽
+        if (autoWidth) {
+            table.autoFit(AutoFitBehavior.FIXED_COLUMN_WIDTHS);
+        }
+        // 设置居中
+        table.setAlignment(CellVerticalAlignment.CENTER);
+        builder.endTable();
+
+        return doc;
+    }
+
+    /**
+     * 向光标当前所在位置创建表格
+     * @param builder
+     * @param clazz
+     * @param list
+     * @return
+     * @throws Exception
+     */
+    public static void createTable(DocumentBuilder builder, Class<?> clazz, List<?> list) throws Exception {
+        // 创建table
+        Table table = builder.startTable();
+        // 获取所有字段
+        Field[] fields = clazz.getDeclaredFields();
+        // 创建表头
+        for (Field field : fields) {
+            // 检查字段是否有自定义注解
+            if (field.isAnnotationPresent(WordTableColumn.class)) {
+                // 获取注解实例
+                WordTableColumn annotation = field.getAnnotation(WordTableColumn.class);
+                // 检查isCreate属性是否为true
+                if (annotation.isCreate()) {
+                    builder.insertCell();
                     builder.getCellFormat().setVerticalAlignment(CellVerticalAlignment.CENTER);
                     ParagraphFormat paragraphFormat = builder.getParagraphFormat();
                     paragraphFormat.setAlignment(ParagraphAlignment.CENTER);
@@ -455,23 +535,26 @@ public class AsposeWordUtil {
         // 设置居中
         table.setAlignment(CellVerticalAlignment.CENTER);
         builder.endTable();
-
-        return doc;
     }
 
     /**
-     * 向光标当前所在位置创建表格
-     * @param builder
+     * 向书签位置插入表格
+     * @param doc
      * @param clazz
      * @param list
+     * @param bookmark
      * @return
      * @throws Exception
      */
-    public static void createTable(DocumentBuilder builder, Class<?> clazz, List<?> list) throws Exception {
+    public static Document createTableWidthStyle(Document doc, Class<?> clazz, List<?> list, String bookmark) throws Exception {
+        // Aspose文档构造器
+        DocumentBuilder builder = new DocumentBuilder(doc);
+        builder.moveToBookmark(bookmark, true, false);
         // 创建table
         Table table = builder.startTable();
         // 获取所有字段
         Field[] fields = clazz.getDeclaredFields();
+
         // 创建表头
         for (Field field : fields) {
             // 检查字段是否有自定义注解
@@ -535,6 +618,19 @@ public class AsposeWordUtil {
         // 设置居中
         table.setAlignment(CellVerticalAlignment.CENTER);
         builder.endTable();
+
+        return doc;
+    }
+
+    public static int findTableIndex(Document doc, Table table) {
+        int index = 0;
+        for (Object t : doc.getChildNodes(NodeType.TABLE, true)) {
+            if (t.equals(table)) {
+                return index;
+            }
+            index++;
+        }
+        return -1; // 未找到
     }
 
 }

+ 134 - 0
common/src/main/java/com/dayou/utils/ExcelConvertToHtmlUtil.java

@@ -62,6 +62,50 @@ public class ExcelConvertToHtmlUtil {
     }
 
     /**
+     * 将excel指定名字的sheet并指定下标的表格转换为html标记语言并返回为字符串
+     * @param lastRowNum   最后一行下标
+     * @param lastColNum   最后一列下标
+     * @param filePath     excel源文件文件的路径
+     * @param isWithStyle  是否需要表格样式 包含 字体 颜色 边框 对齐方式
+     * @param sheetName    要读取的sheet名字
+     * @param type excel文件类型
+     * @return String
+     */
+    public static String readExcelToHtmlCode(String filePath, boolean isWithStyle, String type, String sheetName, int lastRowNum, int lastColNum){
+        InputStream is = null;
+        String htmlExcel = null;
+        Map<String, String> stylemap = new HashMap<String, String>();
+        try {
+            // 不同文件类型处理不一样
+            if ("csv".equalsIgnoreCase(type)) {
+                htmlExcel = getCSVInfo(filePath);
+            } else {
+                File sourcefile = new File(filePath);
+                is = Files.newInputStream(sourcefile.toPath());
+                Workbook wb = WorkbookFactory.create(is);
+                if (wb instanceof XSSFWorkbook) { // 03版excel处理方法
+                    XSSFWorkbook xWb = (XSSFWorkbook) wb;
+                    htmlExcel = getExcelInfoByIndex(xWb, isWithStyle, stylemap, sheetName, lastRowNum, lastColNum);
+                } else if (wb instanceof HSSFWorkbook) { // 07及10版以后的excel处理方法
+                    HSSFWorkbook hWb = (HSSFWorkbook) wb;
+                    htmlExcel = getExcelInfoByIndex(hWb, isWithStyle, stylemap, sheetName, lastRowNum, lastColNum);
+                }
+            }
+            htmlExcel = genHtmlCode(htmlExcel, stylemap, sheetName);
+        } catch (Exception e) {
+            throw new RuntimeException(e.getMessage());
+        } finally {
+            try {
+                if (is != null)
+                    is.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return htmlExcel;
+    }
+
+    /**
      * 将excel指定名字的sheet转换为html标记语言并保存为html文件
      * @param filePath     excel源文件文件的路径
      * @param htmlLocation 生成的html文件的路径
@@ -280,6 +324,96 @@ public class ExcelConvertToHtmlUtil {
         return sb.toString();
     }
 
+    /**
+     * 读取excel文件,返回转换后的html字符串
+     * 指定下标
+     * @param wb          工作簿
+     * @param isWithStyle 是否带上样式
+     * @param stylemap    样式
+     * @return String
+     */
+    private static String getExcelInfoByIndex(Workbook wb, boolean isWithStyle, Map<String, String> stylemap, String sheetName, int lastRowNum, int lastColNum) {
+        StringBuffer sb = new StringBuffer();
+        Sheet sheet = wb.getSheet(sheetName);// 获取指定名称Sheet的内容
+        Map<String, String>[] map = getRowSpanColSpanMap(sheet);
+        sb.append("<table id='table_").append(sheetName).append("' ");
+        sb.append("class='block'");
+        sb.append(">");
+        Row row = null; // 兼容
+        Cell cell = null; // 兼容
+
+        for (int rowNum = sheet.getFirstRowNum(); rowNum <= lastRowNum; rowNum++) {
+            row = sheet.getRow(rowNum);
+            if (row == null) {
+                sb.append("<tr><td ></td></tr>");
+                continue;
+            }
+            sb.append("<tr>");
+            for (int colNum = 0; colNum <= lastColNum; colNum++) {
+                cell = row.getCell(colNum);
+                if (cell == null) { // 特殊情况 空白的单元格会返回null
+                    sb.append("<td> </td>");
+                    continue;
+                }
+                String stringValue = getCellValue(cell);
+                if (map[0].containsKey(rowNum + "," + colNum)) {
+                    String pointString = map[0].get(rowNum + "," + colNum);
+                    map[0].remove(rowNum + "," + colNum);
+                    int bottomeRow = Integer.parseInt(pointString.split(",")[0]);
+                    int bottomeCol = Integer.parseInt(pointString.split(",")[1]);
+                    int rowSpan = bottomeRow - rowNum + 1;
+                    int colSpan = bottomeCol - colNum + 1;
+                    sb.append("<td rowspan= '").append(rowSpan).append("' colspan= '").append(colSpan).append("' ");
+                } else if (map[1].containsKey(rowNum + "," + colNum)) {
+                    map[1].remove(rowNum + "," + colNum);
+                    continue;
+                } else {
+                    sb.append("<td ");
+                }
+
+                // 判断是否需要样式
+                if (isWithStyle) {
+                    dealExcelStyle(wb, sheet, cell, sb, stylemap);// 处理单元格样式
+                }
+
+                sb.append("><nobr>");
+                //如果单元格为空要判断该单元格是不是通过其他单元格计算得到的
+                if (stringValue == null || stringValue.trim().isEmpty()) {
+                    FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
+                    if (evaluator.evaluate(cell) != null) {
+                        //如果单元格的值是通过其他单元格计算来的,则通过单元格计算获取
+                        String cellnumber = evaluator.evaluate(cell).getNumberValue() + "";
+                        //如果单元格的值是小数,保留两位
+                        if (cellnumber.contains(".")) {
+                            String[] decimal = cellnumber.split("\\.");
+                            if (decimal[1].length() > 2) {
+                                int num1 = decimal[1].charAt(0) - '0';
+                                int num2 = decimal[1].charAt(1) - '0';
+                                int num3 = decimal[1].charAt(2) - '0';
+                                if (num3 == 9) {
+                                    num2 = 0;
+                                } else if (num3 >= 5) {
+                                    num2 = num2 + 1;
+                                }
+                                cellnumber = decimal[0] + "." + num1 + num2;
+                            }
+                        }
+                        stringValue = cellnumber;
+                    }
+                    assert stringValue != null;
+                    sb.append(stringValue.replace(String.valueOf((char) 160), " "));
+                } else {
+                    // 将ascii码为160的空格转换为html下的空格( )
+                    sb.append(stringValue.replace(String.valueOf((char) 160), " "));
+                }
+                sb.append("</nobr></td>");
+            }
+            sb.append("</tr>");
+        }
+        sb.append("</table>");
+        return sb.toString();
+    }
+
 
     private static Map<String, String>[] getRowSpanColSpanMap(Sheet sheet) {
         Map<String, String> map0 = new HashMap<String, String>();

+ 4 - 0
domain/pom.xml

@@ -41,6 +41,10 @@
             <groupId>com.fasterxml.jackson.core</groupId>
             <artifactId>jackson-annotations</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.aspose</groupId>
+            <artifactId>aspose-words</artifactId>
+        </dependency>
 
     </dependencies>
     <dependencyManagement>

+ 56 - 0
domain/src/main/java/com/dayou/annotation/WordTableColumn.java

@@ -1,5 +1,6 @@
 package com.dayou.annotation;
 
+import com.aspose.words.*;
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -19,4 +20,59 @@ public @interface WordTableColumn {
      */
     boolean isCreate() default true;
 
+    /**
+     * 单元格垂直对齐(默认居中)
+     */
+    int cellVerticalAlignment() default CellVerticalAlignment.CENTER;
+
+    /**
+     * 对齐方式(默认左对齐,详见ParagraphAlignment)
+     */
+    int paragraphAlignment() default ParagraphAlignment.LEFT;
+
+    /**
+     * 首行缩进
+     */
+    double firstLineIndent() default 0;
+
+    /**
+     * 行高(默认14.175磅,约等于0.5厘米)
+     */
+    double lineSpacing() default 14.175;
+
+    /**
+     * 行高规则(默认最低,详见LineSpacingRule)
+     */
+    int lineSpacingRule() default LineSpacingRule.AT_LEAST;
+
+    /**
+     * 字体(默认宋体)
+     */
+    String fontName() default "宋体";
+
+    /**
+     * 是否加粗标题
+     */
+    boolean titleBold() default false;
+
+    /**
+     * 标题字号(默认小五)
+     */
+    double titleFontSize() default 9;
+
+    /**
+     * 是否加粗内容
+     */
+    boolean bold() default false;
+
+    /**
+     * 字号(默认小五)
+     */
+    double fontSize() default 9;
+
+    /**
+     * 单元格宽度(默认50磅)
+     */
+    double cellWidth() default 50;
+
 }

+ 137 - 0
domain/src/main/java/com/dayou/bo/CRReportFillBO.java

@@ -1,6 +1,8 @@
 package com.dayou.bo;
 
 import com.alibaba.excel.annotation.ExcelProperty;
+import com.dayou.annotation.WordTableColumn;
+import com.dayou.converter.NullToEmptyStringConverter;
 import com.dayou.dto.report.cr.CRReportBaseInfoBO;
 import lombok.Data;
 
@@ -91,15 +93,80 @@ public class CRReportFillBO {
     private String totalLiquidationValueStr;
 
     /**
+     * 优先受偿价值合计
+     */
+    private BigDecimal totalPriorityClaimValue;
+
+    /**
+     * 优先受偿价值合计(千分位格式)
+     */
+    private String totalPriorityClaimValueStr;
+
+    /**
+     * 一般受偿价值合计
+     */
+    private BigDecimal totalGeneralClaimValue;
+
+    /**
+     * 一般受偿价值合计(千分位格式)
+     */
+    private String totalGeneralClaimValueStr;
+
+    /**
+     * 保证受偿价值合计
+     */
+    private BigDecimal totalGuaranteedClaimValue;
+
+    /**
+     * 保证受偿价值合计(千分位格式)
+     */
+    private String totalGuaranteedClaimValueStr;
+
+    /**
+     * 债权可回收金额合计
+     */
+    private BigDecimal totalRecoverableAmount;
+
+    /**
+     * 债权可回收金额合计(千分位格式)
+     */
+    private String totalRecoverableAmountStr;
+
+    /**
+     * 债权清算价值合计
+     */
+    private BigDecimal totalCreditorLiquidationValue;
+
+    /**
+     * 债权清算价值合计(千分位格式)
+     */
+    private String totalCreditorLiquidationValueStr;
+
+    /**
      * 债权分析报告基础信息
      */
     private CRReportBaseInfoBO reportBaseInfo;
 
     /**
+     * 本次所需处置时间
+     */
+    private String timeNeededForThisDisposal;
+
+    /**
+     * 本次清算率取值
+     */
+    private String liquidationRateForThis;
+
+    /**
      * 债权汇总万元表信息
      */
     private List<Consolidated> consolidatedList;
 
+    /**
+     * 综合因素分析表数据
+     */
+    private List<IntegratedAnalysis> integratedAnalysisList;
+
     @Data
     public static class Consolidated {
 
@@ -183,5 +250,75 @@ public class CRReportFillBO {
 
     }
 
+    /**
+     * 综合因素分析
+     */
+    @Data
+    public static class IntegratedAnalysis {
+
+        /**
+         * 折扣
+         */
+        @ExcelProperty(value = "折扣", converter = NullToEmptyStringConverter.class)
+        @WordTableColumn(name = "折扣", fontName = "华文细黑", fontSize = 7.5, titleBold = true, titleFontSize = 8)
+        private String discount;
+
+        /**
+         * 权重
+         */
+        @ExcelProperty(value = "权重", converter = NullToEmptyStringConverter.class)
+        @WordTableColumn(name = "权重", fontName = "华文细黑", fontSize = 7.5, titleBold = true, titleFontSize = 8)
+        private String weight;
+
+        /**
+         * 因素
+         */
+        @ExcelProperty(value = "因素", converter = NullToEmptyStringConverter.class)
+        @WordTableColumn(name = "因素", fontName = "华文细黑", fontSize = 7.5, titleBold = true, titleFontSize = 8)
+        private String factor;
+
+        /**
+         * 序号
+         */
+        @ExcelProperty(value = "序号", converter = NullToEmptyStringConverter.class)
+        @WordTableColumn(name = "序号", fontName = "华文细黑", fontSize = 7.5, titleBold = true, titleFontSize = 8)
+        private String serialNumber;
+
+        /**
+         * 项目
+         */
+        @ExcelProperty(value = "项目", converter = NullToEmptyStringConverter.class)
+        @WordTableColumn(name = "项目", fontName = "华文细黑", fontSize = 7.5, titleBold = true, titleFontSize = 8, cellWidth = 60)
+        private String project;
+
+        /**
+         * 因素描述
+         */
+        @ExcelProperty(value = "因素描述", converter = NullToEmptyStringConverter.class)
+        @WordTableColumn(name = "因素描述", fontName = "华文细黑", fontSize = 7.5, titleBold = true, titleFontSize = 8, cellWidth = 83)
+        private String factorDescription;
+
+        /**
+         * 分值
+         */
+        @ExcelProperty(value = "分值", converter = NullToEmptyStringConverter.class)
+        @WordTableColumn(name = "分值", fontName = "华文细黑", fontSize = 7.5, titleBold = true, titleFontSize = 8)
+        private String score;
+
+        /**
+         * 取值
+         */
+        @ExcelProperty(value = "取值", converter = NullToEmptyStringConverter.class)
+        @WordTableColumn(name = "取值", fontName = "华文细黑", fontSize = 7.5, titleBold = true, titleFontSize = 8)
+        private String value;
+
+        /**
+         * 权重后
+         */
+        @ExcelProperty(value = "权重后", converter = NullToEmptyStringConverter.class)
+        @WordTableColumn(name = "权重后", fontName = "华文细黑", fontSize = 7.5, titleBold = true, titleFontSize = 8)
+        private String weighted;
+    }
+
 
 }

+ 50 - 0
domain/src/main/java/com/dayou/converter/NullToEmptyStringConverter.java

@@ -0,0 +1,50 @@
+package com.dayou.converter;
+
+import com.alibaba.excel.converters.NullableObjectConverter;
+import com.alibaba.excel.enums.CellDataTypeEnum;
+import com.alibaba.excel.metadata.GlobalConfiguration;
+import com.alibaba.excel.metadata.data.ReadCellData;
+import com.alibaba.excel.metadata.data.WriteCellData;
+import com.alibaba.excel.metadata.property.ExcelContentProperty;
+
+public class NullToEmptyStringConverter implements NullableObjectConverter<String> {
+
+    @Override
+    public Class supportJavaTypeKey() {
+        return String.class;
+    }
+
+    @Override
+    public CellDataTypeEnum supportExcelTypeKey() {
+        return CellDataTypeEnum.STRING;
+    }
+
+    @Override
+    public String convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
+        if (cellData.getType() == CellDataTypeEnum.STRING) {
+            if (cellData.getStringValue() == null) {
+                return "";
+            } else {
+                return cellData.getStringValue();
+            }
+        } else if (cellData.getType() == CellDataTypeEnum.NUMBER) {
+            if (cellData.getNumberValue() == null) {
+                return "";
+            } else {
+                return cellData.getNumberValue().toString();
+            }
+        } else if (cellData.getType() == CellDataTypeEnum.BOOLEAN) {
+            if (cellData.getBooleanValue() == null) {
+                return "";
+            } else {
+                return (cellData.getBooleanValue() ? "true" : "false");
+            }
+        }
+        return "";
+    }
+
+    @Override
+    public WriteCellData<?> convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
+        return new WriteCellData<>(value);
+    }
+}

+ 15 - 0
domain/src/main/java/com/dayou/dto/report/cr/CRReportBaseInfoBO.java

@@ -64,6 +64,11 @@ public class CRReportBaseInfoBO {
     private List<Lawsuit> lawsuitList;
 
     /**
+     * 债务人一般受偿能力分析
+     */
+    private String repaymentCapacityAnalysis;
+
+    /**
      * 委托人概况
      */
     @Data
@@ -200,6 +205,11 @@ public class CRReportBaseInfoBO {
          */
         private String guarantorResidence;
 
+        /**
+         * 保证人一般受偿能力分析
+         */
+        private String repaymentCapacityAnalysis;
+
     }
 
     /**
@@ -257,6 +267,11 @@ public class CRReportBaseInfoBO {
          * 经营范围
          */
         private String guarantorBusinessScope;
+
+        /**
+         * 保证人一般受偿能力分析
+         */
+        private String repaymentCapacityAnalysis;
     }
 
     /**

+ 6 - 0
domain/src/main/java/com/dayou/dto/report/cr/DebtorInfoStrBO.java

@@ -24,4 +24,10 @@ public class DebtorInfoStrBO {
     @ExcelProperty("借款企业现状")
     private String statusStr;
 
+    /**
+     * 债务人一般受偿能力分析
+     */
+    @ExcelProperty("债务人一般受偿能力分析")
+    private String repaymentCapacityAnalysisStr;
+
 }

+ 6 - 0
domain/src/main/java/com/dayou/dto/report/cr/GuarantorInfoStrBO.java

@@ -35,4 +35,10 @@ public class GuarantorInfoStrBO {
     @ExcelProperty("保证企业现状")
     private String statusStr;
 
+    /**
+     * 补充偿债来源分析
+     */
+    @ExcelProperty("补充偿债来源分析")
+    private String repaymentCapacityAnalysisStr;
+
 }

+ 143 - 14
service/src/main/java/com/dayou/service/impl/AssetsReportServiceImpl.java

@@ -6,9 +6,7 @@ import com.alibaba.excel.EasyExcel;
 import com.alibaba.excel.ExcelReader;
 import com.alibaba.excel.read.listener.PageReadListener;
 import com.alibaba.excel.read.metadata.ReadSheet;
-import com.aspose.words.Document;
-import com.aspose.words.DocumentBuilder;
-import com.aspose.words.ImportFormatMode;
+import com.aspose.words.*;
 import com.dayou.bo.CRReportFillBO;
 import com.dayou.bo.EqptReportFillBO;
 import com.dayou.config.FileNetConfig;
@@ -41,9 +39,8 @@ import java.math.RoundingMode;
 import java.nio.file.Files;
 import java.nio.file.Paths;
 import java.text.DecimalFormat;
-import java.util.ArrayList;
+import java.util.*;
 import java.util.List;
-import java.util.Optional;
 import java.util.stream.Collectors;
 
 import org.springframework.transaction.annotation.Transactional;
@@ -52,6 +49,7 @@ import static com.dayou.enums.CRReportTmplCode.*;
 import static com.dayou.enums.DocumentType.CR_REPORT;
 import static com.dayou.enums.DocumentType.EQPT_REPORT;
 import static com.dayou.enums.EqptReportTmplCode.*;
+import static com.dayou.utils.AsposeWordUtil.findTableIndex;
 import static com.dayou.utils.EasyExcelUtil.getCellValueByIndex;
 import static com.dayou.utils.EasyExcelUtil.hasColumnIndexGetRowIndexByValue;
 
@@ -486,6 +484,8 @@ public class AssetsReportServiceImpl extends ServiceImpl<AssetsReportMapper, Ass
                 .collect(Collectors.toList());
         // 处理债务人信息
         List<CRReportBaseInfoBO.DebtorInfo> debtorInfoList = new ArrayList<>();
+        // 目前来说只考虑一个债务人的情况,所以只拿第一个元素的受偿分析即可
+        crReportBaseInfoBO.setRepaymentCapacityAnalysis(debtorInfoStrList.get(0).getRepaymentCapacityAnalysisStr());
         for (DebtorInfoStrBO infoStr : debtorInfoStrList) {
             CRReportBaseInfoBO.DebtorInfo debtorInfo = new CRReportBaseInfoBO.DebtorInfo();
             String debtorStr = infoStr.getInfoStr();
@@ -528,6 +528,7 @@ public class AssetsReportServiceImpl extends ServiceImpl<AssetsReportMapper, Ass
             }
             if (infoStr.getGuarantorType().equals("企业")) {
                 CRReportBaseInfoBO.EnterpriseGuarantor enterpriseGuarantor = new CRReportBaseInfoBO.EnterpriseGuarantor();
+                enterpriseGuarantor.setRepaymentCapacityAnalysis(infoStr.getRepaymentCapacityAnalysisStr());
                 String guarantorStr = infoStr.getInfoStr();
                 enterpriseGuarantor.setGuarantorName(guarantorStr.substring(guarantorStr.indexOf("公司名称:") + "公司名称:".length(), guarantorStr.indexOf("\n")));
                 guarantorStr = guarantorStr.replaceFirst("\n", "");
@@ -550,6 +551,7 @@ public class AssetsReportServiceImpl extends ServiceImpl<AssetsReportMapper, Ass
                 enterpriseGuarantorList.add(enterpriseGuarantor);
             } else if (infoStr.getGuarantorType().equals("自然人")) {
                 CRReportBaseInfoBO.PersonGuarantor personGuarantor = new CRReportBaseInfoBO.PersonGuarantor();
+                personGuarantor.setRepaymentCapacityAnalysis(infoStr.getRepaymentCapacityAnalysisStr());
                 String guarantorStr = infoStr.getInfoStr();
                 personGuarantor.setGuarantorName(guarantorStr.substring(guarantorStr.indexOf("姓名:") + "姓名:".length(), guarantorStr.indexOf("\n")));
                 guarantorStr = guarantorStr.replaceFirst("\n", "");
@@ -598,28 +600,54 @@ public class AssetsReportServiceImpl extends ServiceImpl<AssetsReportMapper, Ass
         crReportFillBO.setChineseReportDate(DateToChinese.dateStrConvertChinese(crReportFillBO.getReportBaseInfo().getReportDate()));
 
         // 获取汇总表合计行的下标(用来获取债权汇总表的合计信息)
-        Integer rowindex = hasColumnIndexGetRowIndexByValue(1,"合计",fileNetConfig.getBaseDir() + calculateDoc.getDocUrl(), "汇总表");
-        if (ObjectUtil.isNotNull(rowindex)) {
+        Integer rowindexAggregate = hasColumnIndexGetRowIndexByValue(1,"合计",fileNetConfig.getBaseDir() + calculateDoc.getDocUrl(), "汇总表");
+        if (ObjectUtil.isNotNull(rowindexAggregate)) {
             // 千分位格式处理
             DecimalFormat decimalFormat = new DecimalFormat("#,##0.00");
             // 设置贷款本金
-            crReportFillBO.setLoanPrincipal(new BigDecimal(getCellValueByIndex(rowindex, 2, fileNetConfig.getBaseDir() + calculateDoc.getDocUrl(), "汇总表")));
+            crReportFillBO.setLoanPrincipal(new BigDecimal(getCellValueByIndex(rowindexAggregate, 2, fileNetConfig.getBaseDir() + calculateDoc.getDocUrl(), "汇总表")));
             crReportFillBO.setLoanPrincipalStr(decimalFormat.format(crReportFillBO.getLoanPrincipal()));
             // 设置应收利息(含罚息)
-            crReportFillBO.setInterest(new BigDecimal(getCellValueByIndex(rowindex, 3, fileNetConfig.getBaseDir() + calculateDoc.getDocUrl(), "汇总表")));
+            crReportFillBO.setInterest(new BigDecimal(getCellValueByIndex(rowindexAggregate, 3, fileNetConfig.getBaseDir() + calculateDoc.getDocUrl(), "汇总表")));
             crReportFillBO.setInterestStr(decimalFormat.format(crReportFillBO.getInterest()));
             // 设置其他费用
-            crReportFillBO.setOtherExpenses(new BigDecimal(getCellValueByIndex(rowindex, 4, fileNetConfig.getBaseDir() + calculateDoc.getDocUrl(), "汇总表")));
+            crReportFillBO.setOtherExpenses(new BigDecimal(getCellValueByIndex(rowindexAggregate, 4, fileNetConfig.getBaseDir() + calculateDoc.getDocUrl(), "汇总表")));
             crReportFillBO.setOtherExpensesStr(decimalFormat.format(crReportFillBO.getOtherExpenses()));
             // 设置各项债权合计
-            crReportFillBO.setCRTotal(new BigDecimal(getCellValueByIndex(rowindex, 5, fileNetConfig.getBaseDir() + calculateDoc.getDocUrl(), "汇总表")));
+            crReportFillBO.setCRTotal(new BigDecimal(getCellValueByIndex(rowindexAggregate, 5, fileNetConfig.getBaseDir() + calculateDoc.getDocUrl(), "汇总表")));
             crReportFillBO.setCRTotalStr(decimalFormat.format(crReportFillBO.getCRTotal()));
-
             // 设置债权清算价值
-            crReportFillBO.setTotalLiquidationValue(new BigDecimal(getCellValueByIndex(rowindex, 11, fileNetConfig.getBaseDir() + calculateDoc.getDocUrl(), "汇总表")));
+            crReportFillBO.setTotalLiquidationValue(new BigDecimal(getCellValueByIndex(rowindexAggregate, 11, fileNetConfig.getBaseDir() + calculateDoc.getDocUrl(), "汇总表")));
             crReportFillBO.setTotalLiquidationValueStr(decimalFormat.format(crReportFillBO.getTotalLiquidationValue()));
         }
 
+        // 获取汇总表合计行的下标(用来获取债权汇总表的合计信息)
+        Integer rowindexAggregateTenThousand = hasColumnIndexGetRowIndexByValue(1,"合计",fileNetConfig.getBaseDir() + calculateDoc.getDocUrl(), "汇总万元表");
+        if (ObjectUtil.isNotNull(rowindexAggregateTenThousand)) {
+            // 千分位格式处理
+            DecimalFormat decimalFormat = new DecimalFormat("#,##0.00");
+            // 设置优先受偿价值合计
+            crReportFillBO.setTotalPriorityClaimValue(new BigDecimal(getCellValueByIndex(rowindexAggregateTenThousand, 6, fileNetConfig.getBaseDir() + calculateDoc.getDocUrl(), "汇总万元表")));
+            crReportFillBO.setTotalPriorityClaimValueStr(decimalFormat.format(crReportFillBO.getTotalPriorityClaimValue()));
+            // 设置一般受偿价值合计
+            crReportFillBO.setTotalGeneralClaimValue(new BigDecimal(getCellValueByIndex(rowindexAggregateTenThousand, 7, fileNetConfig.getBaseDir() + calculateDoc.getDocUrl(), "汇总万元表")));
+            crReportFillBO.setTotalGeneralClaimValueStr(decimalFormat.format(crReportFillBO.getTotalGeneralClaimValue()));
+            // 设置保证受偿价值合计
+            crReportFillBO.setTotalGuaranteedClaimValue(new BigDecimal(getCellValueByIndex(rowindexAggregateTenThousand, 8, fileNetConfig.getBaseDir() + calculateDoc.getDocUrl(), "汇总万元表")));
+            crReportFillBO.setTotalGuaranteedClaimValueStr(decimalFormat.format(crReportFillBO.getTotalGuaranteedClaimValue()));
+            // 设置债权可回收金额合计
+            crReportFillBO.setTotalRecoverableAmount(new BigDecimal(getCellValueByIndex(rowindexAggregateTenThousand, 9, fileNetConfig.getBaseDir() + calculateDoc.getDocUrl(), "汇总万元表")));
+            crReportFillBO.setTotalRecoverableAmountStr(decimalFormat.format(crReportFillBO.getTotalRecoverableAmount()));
+
+            // 设置债权清算价值合计
+            crReportFillBO.setTotalCreditorLiquidationValue(new BigDecimal(getCellValueByIndex(rowindexAggregateTenThousand, 11, fileNetConfig.getBaseDir() + calculateDoc.getDocUrl(), "汇总万元表")));
+            crReportFillBO.setTotalCreditorLiquidationValueStr(decimalFormat.format(crReportFillBO.getTotalCreditorLiquidationValue()));
+        }
+
+        // 设置本次所需处置时间与清算率取值
+        crReportFillBO.setTimeNeededForThisDisposal(getCellValueByIndex(66, 1, fileNetConfig.getBaseDir() + calculateDoc.getDocUrl(), "债权清算率"));
+        crReportFillBO.setLiquidationRateForThis(String.valueOf(new Double(getCellValueByIndex(66, 2, fileNetConfig.getBaseDir() + calculateDoc.getDocUrl(), "债权清算率")) * 100));
+
         // 获取汇总万元表合计行的下标
         Integer allSheetRowIndex = hasColumnIndexGetRowIndexByValue(1,"合计",fileNetConfig.getBaseDir() + calculateDoc.getDocUrl(), "汇总万元表");
         if (ObjectUtil.isNotNull(allSheetRowIndex)) {
@@ -635,6 +663,15 @@ public class AssetsReportServiceImpl extends ServiceImpl<AssetsReportMapper, Ass
         consolidatedList.remove(consolidatedList.size() - 1);
         crReportFillBO.setConsolidatedList(consolidatedList);
 
+        // 读取综合因素分析表信息
+        List<CRReportFillBO.IntegratedAnalysis> integratedAnalysisList =  EasyExcel.read(fileNetConfig.getBaseDir() + calculateDoc.getDocUrl()).head(CRReportFillBO.IntegratedAnalysis.class).sheet("债权清算率").doReadSync();
+        for (int i = 0; i < 56; i++) {
+            if (ObjectUtil.isNotEmpty(integratedAnalysisList.get(i).getWeight())) {
+                integratedAnalysisList.get(i).setWeight( (int) (new Double(integratedAnalysisList.get(i).getWeight()) * 100) + "%");
+            }
+        }
+        crReportFillBO.setIntegratedAnalysisList(integratedAnalysisList.subList(0, 56)); // 后边的信息是清算率信息,此处不需要
+
         // 第一步:设置封面
         // 封面模板文件位置
         String coverTmplPath = fileNetConfig.getBaseDir() + coverTmpl.getSectionFileUrl() + coverTmpl.getSectionFileName();
@@ -757,7 +794,7 @@ public class AssetsReportServiceImpl extends ServiceImpl<AssetsReportMapper, Ass
             lawsuitIs.close();
         }
 
-        // 诉讼情况信息模板文件位置
+        // 保证人补充偿债来源分析
         String guarantorAdditionalDebtRepaymentSourcesPath = fileNetConfig.getBaseDir() + guarantorAdditionalDebtRepaymentSourcesTmpl.getSectionFileUrl() + guarantorAdditionalDebtRepaymentSourcesTmpl.getSectionFileName();
         // 插入时会导致先插入的排在后插入的后面,所以把顺序反转一下(企业和自然人用同一个序号排序)
         for (int i = guarantorInfoStrBOList.size(); i > 0; i--) {
@@ -798,6 +835,92 @@ public class AssetsReportServiceImpl extends ServiceImpl<AssetsReportMapper, Ass
         // 将目录插入到框架
         AsposeWordUtil.insertDocumentAfterBookMark(mainDoc, catalogueDoc, "insertCatalogue", false, false);
 
+        // 创建综合因素分析表
+        Document tableDoc = new Document();
+        DocumentBuilder tableBuilder = new DocumentBuilder(tableDoc);
+        tableBuilder.startBookmark("table");
+        tableBuilder.endBookmark("table");
+        AsposeWordUtil.createTable(tableDoc, CRReportFillBO.IntegratedAnalysis.class, crReportFillBO.getIntegratedAnalysisList(), "table", false);
+        //将第一列整列合并
+        tableBuilder.moveToCell(0,1,0,0);
+        tableBuilder.getCellFormat().setVerticalMerge(CellMerge.FIRST);//合并的第一个单元格 保留的值是第一个单元格的值
+        for(int i = 2; i < 56; i++ ) {
+            tableBuilder.moveToCell(0, i, 0, 0);
+            tableBuilder.getCellFormat().setVerticalMerge(CellMerge.PREVIOUS);
+        }
+        //将第二列第2行合并到31行
+        tableBuilder.moveToCell(0,1,1,0);
+        tableBuilder.getCellFormat().setVerticalMerge(CellMerge.FIRST);//合并的第一个单元格 保留的值是第一个单元格的值
+        for(int i = 2; i < 31; i++ ) {
+            tableBuilder.moveToCell(0, i, 1, 0);
+            tableBuilder.getCellFormat().setVerticalMerge(CellMerge.PREVIOUS);
+        }
+        //将第二列第33行合并到38行
+        tableBuilder.moveToCell(0,32,1,0);
+        tableBuilder.getCellFormat().setVerticalMerge(CellMerge.FIRST);//合并的第一个单元格 保留的值是第一个单元格的值
+        for(int i = 33; i < 38; i++ ) {
+            tableBuilder.moveToCell(0, i, 1, 0);
+            tableBuilder.getCellFormat().setVerticalMerge(CellMerge.PREVIOUS);
+        }
+        //将第二列第40行合并到47行
+        tableBuilder.moveToCell(0,39,1,0);
+        tableBuilder.getCellFormat().setVerticalMerge(CellMerge.FIRST);//合并的第一个单元格 保留的值是第一个单元格的值
+        for(int i = 40; i < 47; i++ ) {
+            tableBuilder.moveToCell(0, i, 1, 0);
+            tableBuilder.getCellFormat().setVerticalMerge(CellMerge.PREVIOUS);
+        }
+        //将第二列第49行合并到51行
+        tableBuilder.moveToCell(0,48,1,0);
+        tableBuilder.getCellFormat().setVerticalMerge(CellMerge.FIRST);//合并的第一个单元格 保留的值是第一个单元格的值
+        for(int i = 49; i < 51; i++ ) {
+            tableBuilder.moveToCell(0, i, 1, 0);
+            tableBuilder.getCellFormat().setVerticalMerge(CellMerge.PREVIOUS);
+        }
+        //将第二列第53行合并到55行
+        tableBuilder.moveToCell(0,52,1,0);
+        tableBuilder.getCellFormat().setVerticalMerge(CellMerge.FIRST);//合并的第一个单元格 保留的值是第一个单元格的值
+        for(int i = 53; i < 55; i++ ) {
+            tableBuilder.moveToCell(0, i, 1, 0);
+            tableBuilder.getCellFormat().setVerticalMerge(CellMerge.PREVIOUS);
+        }
+
+        //将第三列第2行合并到31行
+        tableBuilder.moveToCell(0,1,2,0);
+        tableBuilder.getCellFormat().setVerticalMerge(CellMerge.FIRST);//合并的第一个单元格 保留的值是第一个单元格的值
+        for(int i = 2; i < 31; i++ ) {
+            tableBuilder.moveToCell(0, i, 2, 0);
+            tableBuilder.getCellFormat().setVerticalMerge(CellMerge.PREVIOUS);
+        }
+        //将第二列第33行合并到38行
+        tableBuilder.moveToCell(0,32,2,0);
+        tableBuilder.getCellFormat().setVerticalMerge(CellMerge.FIRST);//合并的第一个单元格 保留的值是第一个单元格的值
+        for(int i = 33; i < 38; i++ ) {
+            tableBuilder.moveToCell(0, i, 2, 0);
+            tableBuilder.getCellFormat().setVerticalMerge(CellMerge.PREVIOUS);
+        }
+        //将第二列第40行合并到47行
+        tableBuilder.moveToCell(0,39,2,0);
+        tableBuilder.getCellFormat().setVerticalMerge(CellMerge.FIRST);//合并的第一个单元格 保留的值是第一个单元格的值
+        for(int i = 40; i < 47; i++ ) {
+            tableBuilder.moveToCell(0, i, 2, 0);
+            tableBuilder.getCellFormat().setVerticalMerge(CellMerge.PREVIOUS);
+        }
+        //将第二列第49行合并到51行
+        tableBuilder.moveToCell(0,48,2,0);
+        tableBuilder.getCellFormat().setVerticalMerge(CellMerge.FIRST);//合并的第一个单元格 保留的值是第一个单元格的值
+        for(int i = 49; i < 51; i++ ) {
+            tableBuilder.moveToCell(0, i, 2, 0);
+            tableBuilder.getCellFormat().setVerticalMerge(CellMerge.PREVIOUS);
+        }
+        //将第二列第53行合并到55行
+        tableBuilder.moveToCell(0,52,2,0);
+        tableBuilder.getCellFormat().setVerticalMerge(CellMerge.FIRST);//合并的第一个单元格 保留的值是第一个单元格的值
+        for(int i = 53; i < 55; i++ ) {
+            tableBuilder.moveToCell(0, i, 2, 0);
+            tableBuilder.getCellFormat().setVerticalMerge(CellMerge.PREVIOUS);
+        }
+        AsposeWordUtil.insertDocumentAfterBookMark(mainDoc, tableDoc, "insertIntegratedAnalysis", false, false);
+
         // 第七步:删除预留书签插入位置的空白行
         DocumentBuilder mainBuilder = new DocumentBuilder(mainDoc);
         mainBuilder.moveToBookmark("insertDetail");
@@ -818,6 +941,12 @@ public class AssetsReportServiceImpl extends ServiceImpl<AssetsReportMapper, Ass
         mainBuilder.getCurrentParagraph().remove();
         mainBuilder.moveToBookmark("insertLawsuit");
         mainBuilder.getCurrentParagraph().remove();
+        mainBuilder.moveToBookmark("insertIntegratedAnalysis");
+        mainBuilder.getCurrentParagraph().remove();
+        mainBuilder.moveToBookmark("insertGuarantorAdditionalDebtRepaymentSo");
+        mainBuilder.getCurrentParagraph().remove();
+        mainBuilder.moveToBookmark("table");
+        mainBuilder.getCurrentParagraph().remove();
 
         // 第八步:生成并保存文档
         // 将封面和文档进行拼接

+ 1 - 1
service/src/main/java/com/dayou/service/impl/HouseGuarantyServiceImpl.java

@@ -397,7 +397,7 @@ public class HouseGuarantyServiceImpl implements HouseGuarantyService {
                 return entityTable;
             }).collect(Collectors.toList());
             //生成文档中的表格
-            AsposeWordUtil.createTable(doc, HouseEntityTable.class, entityTables, "buildingInfo");
+            AsposeWordUtil.createTableWidthStyle(doc, HouseEntityTable.class, entityTables, "buildingInfo");
             doc.save(baseDir + guarantyResultName);
             //更新过程文档url
             HouseGuarantyProcess houseGuarantyProcess = new HouseGuarantyProcess();