zhaojinyu 4 hónapja
commit
8409c0f9ac
100 módosított fájl, 10289 hozzáadás és 0 törlés
  1. 8 0
      .idea/.gitignore
  2. 21 0
      .idea/compiler.xml
  3. 11 0
      .idea/encodings.xml
  4. 20 0
      .idea/jarRepositories.xml
  5. 12 0
      .idea/misc.xml
  6. 4 0
      .idea/vcs.xml
  7. 45 0
      README.md
  8. BIN
      allatori/allatori.jar
  9. 36 0
      allatori/allatori.xml
  10. BIN
      allatori/class-winter-core-enhance-2.9.4.jar
  11. BIN
      allatori/class-winter-maven-plugin-enhance-2.9.4.jar
  12. 37 0
      allatori/class-winter-maven-plugin-pom.xml
  13. 159 0
      jnpf-datareport-univer-common/pom.xml
  14. 12 0
      jnpf-datareport-univer-common/src/main/java/jnpf/consts/ApiConst.java
  15. 208 0
      jnpf-datareport-univer-common/src/main/java/jnpf/exception/ResultException.java
  16. 8 0
      jnpf-datareport-univer-common/src/main/java/jnpf/properties/ReportProperties.java
  17. 206 0
      jnpf-datareport-univer-common/src/main/java/jnpf/util/ChartUtil.java
  18. 26 0
      jnpf-datareport-univer-common/src/main/java/jnpf/util/DeepCopy.java
  19. 134 0
      jnpf-datareport-univer-common/src/main/java/jnpf/util/ImageUtil.java
  20. 95 0
      jnpf-datareport-univer-common/src/main/java/jnpf/util/ReportUtil.java
  21. 2471 0
      jnpf-datareport-univer-common/src/main/java/jnpf/util/UniverConvert.java
  22. 1148 0
      jnpf-datareport-univer-common/src/main/java/jnpf/util/UniverExcel.java
  23. 154 0
      jnpf-datareport-univer-common/src/main/java/jnpf/util/ZxingUtil.java
  24. 16 0
      jnpf-datareport-univer-common/src/main/java/jnpf/util/excel/ExcelParser.java
  25. 346 0
      jnpf-datareport-univer-common/src/main/java/jnpf/util/excel/ImportExcel.java
  26. 21 0
      jnpf-datareport-univer-common/src/main/java/jnpf/util/excel/ImportExcelParser.java
  27. 397 0
      jnpf-datareport-univer-common/src/main/java/jnpf/util/excel/ImportHssfExcel.java
  28. 557 0
      jnpf-datareport-univer-common/src/main/java/jnpf/util/excel/ImportXssfExcel.java
  29. 686 0
      jnpf-datareport-univer-common/src/main/java/jnpf/util/excel/UniverHSSFExcel.java
  30. 846 0
      jnpf-datareport-univer-common/src/main/java/jnpf/util/excel/UniverXSSFExcel.java
  31. 174 0
      jnpf-datareport-univer-model/pom.xml
  32. 11 0
      jnpf-datareport-univer-model/src/main/java/jnpf/enums/CellDataEnum.java
  33. 31 0
      jnpf-datareport-univer-model/src/main/java/jnpf/enums/CellDataTypeEnum.java
  34. 19 0
      jnpf-datareport-univer-model/src/main/java/jnpf/enums/ColumnEnum.java
  35. 22 0
      jnpf-datareport-univer-model/src/main/java/jnpf/enums/FormatTypeEnum.java
  36. 46 0
      jnpf-datareport-univer-model/src/main/java/jnpf/enums/HorizontalEnum.java
  37. 11 0
      jnpf-datareport-univer-model/src/main/java/jnpf/enums/ImageEnum.java
  38. 11 0
      jnpf-datareport-univer-model/src/main/java/jnpf/enums/OperatorEnum.java
  39. 57 0
      jnpf-datareport-univer-model/src/main/java/jnpf/enums/ResourceEnum.java
  40. 43 0
      jnpf-datareport-univer-model/src/main/java/jnpf/enums/StyleTypeEnum.java
  41. 52 0
      jnpf-datareport-univer-model/src/main/java/jnpf/enums/SubTypeEnum.java
  42. 50 0
      jnpf-datareport-univer-model/src/main/java/jnpf/enums/UniverDataEnum.java
  43. 52 0
      jnpf-datareport-univer-model/src/main/java/jnpf/enums/ValidationType.java
  44. 46 0
      jnpf-datareport-univer-model/src/main/java/jnpf/enums/VerticalEnum.java
  45. 37 0
      jnpf-datareport-univer-model/src/main/java/jnpf/enums/ZxingEnum.java
  46. 51 0
      jnpf-datareport-univer-model/src/main/java/jnpf/enums/operatorTypeEnum.java
  47. 51 0
      jnpf-datareport-univer-model/src/main/java/jnpf/model/ColumnList.java
  48. 20 0
      jnpf-datareport-univer-model/src/main/java/jnpf/model/DataQuery.java
  49. 16 0
      jnpf-datareport-univer-model/src/main/java/jnpf/model/DataSortModel.java
  50. 19 0
      jnpf-datareport-univer-model/src/main/java/jnpf/model/Fence.java
  51. 25 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/chart/UniverChartField.java
  52. 18 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/chart/UniverChartModel.java
  53. 20 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/data/cell/UniverCell.java
  54. 57 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/data/cell/UniverDataConfig.java
  55. 20 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/data/custom/UniverCustom.java
  56. 27 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/data/resource/UniverConfig.java
  57. 20 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/data/resource/UniverCustomFilters.java
  58. 9 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/data/resource/UniverData.java
  59. 40 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/data/resource/UniverDrawing.java
  60. 16 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/data/resource/UniverFilters.java
  61. 17 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/data/resource/UniverNum.java
  62. 17 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/data/resource/UniverOffset.java
  63. 20 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/data/resource/UniverRef.java
  64. 23 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/data/resource/UniverRule.java
  65. 34 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/data/resource/UniverTransform.java
  66. 15 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/data/resource/UniverValue.java
  67. 36 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/model/UniverPreview.java
  68. 37 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/model/UniverWorkBook.java
  69. 24 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/properties/UniverBody.java
  70. 67 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/properties/UniverBodyConfig.java
  71. 43 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/properties/UniverDocumentStyle.java
  72. 22 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/properties/UniverDocumentStyleConfig.java
  73. 33 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/properties/UniverProperties.java
  74. 16 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/resources/UniverResource.java
  75. 67 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/resources/UniverResourceData.java
  76. 38 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/sheet/UniverSheet.java
  77. 17 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/sheet/UniverSheetCell.java
  78. 43 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/sheet/UniverSheetCellData.java
  79. 23 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/sheet/UniverSheetColumnData.java
  80. 17 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/sheet/UniverSheetColumnHeader.java
  81. 19 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/sheet/UniverSheetFreeze.java
  82. 47 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/sheet/UniverSheetRange.java
  83. 31 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/sheet/UniverSheetRowData.java
  84. 17 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/sheet/UniverSheetRowHeader.java
  85. 98 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/style/UniverStyle.java
  86. 35 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/style/UniverStyleBorder.java
  87. 17 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/style/UniverStyleBorderStyle.java
  88. 17 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/style/UniverStyleColor.java
  89. 19 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/style/UniverStylePadding.java
  90. 14 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/style/UniverStylePattern.java
  91. 23 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/style/UniverStyleTextDecoration.java
  92. 25 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/style/UniverStyleTextRotation.java
  93. 40 0
      jnpf-datareport-univer-model/src/main/java/jnpf/univer/zxing/UniverZxingModel.java
  94. 16 0
      jnpf-datareport-univer-model/src/main/java/jnpf/ureport/Range.java
  95. 16 0
      jnpf-datareport-univer-model/src/main/java/jnpf/ureport/build/BindData.java
  96. 173 0
      jnpf-datareport-univer-model/src/main/java/jnpf/ureport/build/Context.java
  97. 31 0
      jnpf-datareport-univer-model/src/main/java/jnpf/ureport/build/DataCompute.java
  98. 15 0
      jnpf-datareport-univer-model/src/main/java/jnpf/ureport/build/Dataset.java
  99. 34 0
      jnpf-datareport-univer-model/src/main/java/jnpf/ureport/build/DatasetUtils.java
  100. 238 0
      jnpf-datareport-univer-model/src/main/java/jnpf/ureport/build/ReportBuilder.java

+ 8 - 0
.idea/.gitignore

@@ -0,0 +1,8 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml
+# 基于编辑器的 HTTP 客户端请求
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml

+ 21 - 0
.idea/compiler.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="CompilerConfiguration">
+    <annotationProcessing>
+      <profile name="Maven default annotation processors profile" enabled="true">
+        <sourceOutputDir name="target/generated-sources/annotations" />
+        <sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
+        <outputRelativeToContentRoot value="true" />
+        <module name="jnpf-datareport-univer-model" />
+        <module name="jnpf-datareport-univer-common" />
+      </profile>
+    </annotationProcessing>
+  </component>
+  <component name="JavacSettings">
+    <option name="ADDITIONAL_OPTIONS_OVERRIDE">
+      <module name="jnpf-datareport-univer-common" options="-parameters" />
+      <module name="jnpf-datareport-univer-core" options="-parameters" />
+      <module name="jnpf-datareport-univer-model" options="-parameters" />
+    </option>
+  </component>
+</project>

+ 11 - 0
.idea/encodings.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Encoding">
+    <file url="file://$PROJECT_DIR$/jnpf-datareport-univer-common/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-datareport-univer-common/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-datareport-univer-model/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-datareport-univer-model/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
+  </component>
+</project>

+ 20 - 0
.idea/jarRepositories.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="RemoteRepositoriesConfiguration">
+    <remote-repository>
+      <option name="id" value="central" />
+      <option name="name" value="Central Repository" />
+      <option name="url" value="http://127.0.0.1:9999/repository/maven-public/" />
+    </remote-repository>
+    <remote-repository>
+      <option name="id" value="central" />
+      <option name="name" value="Maven Central repository" />
+      <option name="url" value="https://repo1.maven.org/maven2" />
+    </remote-repository>
+    <remote-repository>
+      <option name="id" value="jboss.community" />
+      <option name="name" value="JBoss Community repository" />
+      <option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
+    </remote-repository>
+  </component>
+</project>

+ 12 - 0
.idea/misc.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ExternalStorageConfigurationManager" enabled="true" />
+  <component name="MavenProjectsManager">
+    <option name="originalFiles">
+      <list>
+        <option value="$PROJECT_DIR$/pom.xml" />
+      </list>
+    </option>
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK" />
+</project>

+ 4 - 0
.idea/vcs.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings" defaultProject="true" />
+</project>

+ 45 - 0
README.md

@@ -0,0 +1,45 @@
+> 特别说明:源码、JDK、数据库、Redis等安装或存放路径禁止包含中文、空格、特殊字符等
+
+## 一 环境要求
+
+| 类目 | 版本说明或建议           |
+| --- |------------------|
+| 硬件 | 开发电脑建议使用I3及以上CPU,16G及以上内存  |
+| 操作系统 | Windows 10/11,MacOS |
+| JDK | 默认使用JDK 21,如需要切换JDK 8/11/17版本请参考文档调整代码,推荐使用 `OpenJDK`,如 `Liberica JDK`、`Eclipse Temurin`、`Alibaba Dragonwell`、`BiSheng`等发行版; |
+| Maven | 依赖管理工具,推荐使用 `3.6.3` 及以上版本  |
+| IDE   | 代码集成开发环境,推荐使用 `IDEA2024` 及以上版本,兼容 `Eclipse`、 `Spring Tool Suite` 等IDE工具 |
+
+## 二 关联项目
+> 为以下项目提供基础依赖
+
+| 项目            | 分支            | 说明         |
+|---------------|---------------|------------|
+| jnpf-java-datareport-univer | v6.0.x-stable  | Univer报表源码 |
+
+## 三 选择是否加密
+
+> 是否加密将会影响 `jnpf-java-datareport-univer` 项目的启动方式
+> 如果此项目选择加密 `jnpf-java-datareport-univer` 项目也需要选择加密
+
+### 3.1 不使用加密
+
+在IDEA中, 展开右侧 `Maven` 中 `Profiles` 去除勾选 `encrypted` 选项, 再点击Maven `刷新` 图标刷新 Maven
+
+### 3.2 使用加密
+
+在IDEA中, 展开右侧 `Maven` 中 `Profiles` 勾选 `encrypted` 选项, 再点击Maven `刷新` 图标刷新 Maven
+
+#### 3.2.1 安装加密插件
+
+在IDEA中,双击右侧 `Maven` 中 `jnpf-datareport-univer-core` > `clean` 将会自动安装加密打包插件
+
+## 四 使用方式
+
+### 4.1 本地安装
+
+在IDEA中,双击右侧 `Maven` 中 `jnpf-datareport-univer-core` > `Lifecycle` > `install`,将 `jnpf-datareport-univer-core` 包安装至本地
+
+### 4.2 发布到私服
+
+在IDEA中,双击右侧 `Maven` 中 `jnpf-datareport-univer-core` > `Lifecycle` > `deploy` 发布至私服。

BIN
allatori/allatori.jar


+ 36 - 0
allatori/allatori.xml

@@ -0,0 +1,36 @@
+<config>
+    <input>
+        <jar in="${project.build.finalName}.jar" out="${project.build.finalName}.jar"/>
+    </input>
+
+    <keep-names>
+        <class access="protected+">
+            <field access="protected+"/>
+            <method access="protected+"/>
+        </class>
+    </keep-names>
+    <ignore-classes>
+        <!-- 注意:spring的框架相关的文件需要排除,避免启动报错 -->
+        <class template="class jnpf.properties.ReportProperties"/>
+        <class template="class jnpf.univer.*"/>
+    </ignore-classes>
+
+
+    <!-- 混淆设置 -->
+    <!--随机类名保持小写-->
+    <property name="classes-naming" value="abc"/>
+    <!-- 接口形参名保持不变 -->
+    <property name="local-variables-naming" value="keep-parameters"/>
+    <!-- 字符串加密 -->
+    <property name="string-encryption" value="maximum"/>
+    <property name="string-encryption-type" value="strong"/>
+    <property name="string-encryption-version" value="v4"/>
+    <!-- 行数混淆 -->
+    <property name="line-numbers" value="obfuscate"/>
+    <!-- 成员重新排序 -->
+    <property name="member-reorder" value="enable"/>
+    <!-- 数据jar压缩等级 -->
+    <property name="output-jar-compression-level" value="9"/>
+
+    <property name="log-file" value="log.xml"/>
+</config>

BIN
allatori/class-winter-core-enhance-2.9.4.jar


BIN
allatori/class-winter-maven-plugin-enhance-2.9.4.jar


+ 37 - 0
allatori/class-winter-maven-plugin-pom.xml

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.idea-aedi</groupId>
+    <artifactId>class-winter-maven-plugin</artifactId>
+    <version>enhance-2.9.4</version>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.idea-aedi</groupId>
+            <artifactId>class-winter-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-plugin-api</artifactId>
+            <version>3.8.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.maven.plugin-tools</groupId>
+            <artifactId>maven-plugin-annotations</artifactId>
+            <version>3.6.1</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-project</artifactId>
+            <version>2.2.1</version>
+        </dependency>
+    </dependencies>
+</project>

+ 159 - 0
jnpf-datareport-univer-common/pom.xml

@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.jnpf</groupId>
+        <artifactId>jnpf-datareport-univer-core</artifactId>
+        <version>6.0.0-RELEASE</version>
+    </parent>
+
+    <artifactId>jnpf-datareport-univer-common</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.jnpf</groupId>
+            <artifactId>jnpf-common-database</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.jnpf</groupId>
+            <artifactId>jnpf-common-swagger</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.jnpf</groupId>
+            <artifactId>jnpf-common-file</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi</artifactId>
+            <version>${poi.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml-full</artifactId>
+            <version>${poi.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml</artifactId>
+            <version>${poi.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.jnpf</groupId>
+            <artifactId>jnpf-datareport-univer-model</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+
+    <profiles>
+
+        <profile>
+            <id>encrypted</id>
+            <build>
+                <plugins>
+                    <!--复制驱动包, 供后续加密使用-->
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-dependency-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>copy-dependencies</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>copy-dependencies</goal>
+                                </goals>
+                                <configuration>
+                                    <includeGroupIds>com.jnpf,org.apache.poi,cn.dev33,cn.hutool,org.apache.poi,org.springframework,org.apache.tomcat.embed</includeGroupIds>
+                                    <includeArtifactIds>jnpf-common-core,poi,sa-token-core,hutool-all,poi-ooxml,spring-web,tomcat-embed-core</includeArtifactIds>
+                                    <outputDirectory>${project.build.directory}/copylib</outputDirectory>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <!--复制allatori配置重写配置中的包路径-->
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-resources-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>copy-and-filter-allatori-config</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>copy-resources</goal>
+                                </goals>
+                                <configuration>
+                                    <outputDirectory>${project.build.directory}</outputDirectory>
+                                    <resources>
+                                        <resource>
+                                            <directory>${project.basedir}/../allatori</directory>
+                                            <includes>
+                                                <include>allatori.xml</include>
+                                            </includes>
+                                            <filtering>true</filtering>
+                                        </resource>
+                                    </resources>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <!--Jar混淆-->
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>exec-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>run-allatori</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>exec</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                        <configuration>
+                            <executable>java</executable>
+                            <arguments>
+                                <argument>-Xms128m</argument>
+                                <argument>-Xmx512m</argument>
+                                <argument>-jar</argument>
+                                <!-- Copy allatori.jar to 'allatori' directory to use the commented line -->
+                                <argument>${project.basedir}/../allatori/allatori.jar</argument>
+                                <!-- <argument>${basedir}/allatori/allatori.jar</argument> -->
+                                <argument>${project.build.directory}/allatori.xml</argument>
+                            </arguments>
+                        </configuration>
+                    </plugin>
+                    <!--Jar加密-->
+                    <plugin>
+                        <groupId>com.idea-aedi</groupId>
+                        <artifactId>class-winter-maven-plugin</artifactId>
+                        <!-- 相关配置 -->
+                        <configuration>
+                            <!--需要处理的包名-->
+                            <includePrefix>jnpf</includePrefix>
+                            <!--直接覆盖原文件-->
+                            <finalName>${build.finalName}</finalName>
+                            <!--编译中依赖的第三方包路径-->
+                            <supportFile>${project.build.directory}/copylib</supportFile>
+                            <!--检查启动参数-->
+                            <jvmArgCheck>-XX:+DisableAttachMechanism</jvmArgCheck>
+                        </configuration>
+                        <executions>
+                            <execution>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>class-winter</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+
+</project>

+ 12 - 0
jnpf-datareport-univer-common/src/main/java/jnpf/consts/ApiConst.java

@@ -0,0 +1,12 @@
+package jnpf.consts;
+
+public class ApiConst {
+
+    public static String ME;
+    public static String DATASET_LIST;
+    public static String DATASET_SAVE;
+    public static String DATASET_DATA;
+    public static String SAVE_MENU;
+    public static String GET_MENU;
+    public static String PARAMETER_DATA;
+}

+ 208 - 0
jnpf-datareport-univer-common/src/main/java/jnpf/exception/ResultException.java

@@ -0,0 +1,208 @@
+package jnpf.exception;
+
+import cn.dev33.satoken.exception.NotLoginException;
+import cn.dev33.satoken.exception.NotPermissionException;
+import cn.dev33.satoken.exception.NotRoleException;
+import cn.dev33.satoken.exception.SameTokenInvalidException;
+import com.alibaba.fastjson.JSON;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import jnpf.base.ActionResult;
+import jnpf.base.ActionResultCode;
+import jnpf.config.ConfigValueUtil;
+import jnpf.constant.MsgCode;
+import jnpf.util.*;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.web.ErrorProperties;
+import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
+import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Controller;
+import org.springframework.validation.ObjectError;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author JNPF开发平台组
+ * @version V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date 2021/3/16 10:10
+ */
+@Slf4j
+@Controller
+@ControllerAdvice
+public class ResultException extends BasicErrorController {
+
+    @Autowired
+    private ConfigValueUtil configValueUtil;
+
+    public ResultException(){
+        super(new DefaultErrorAttributes(), new ErrorProperties());
+    }
+
+    @ResponseBody
+    @ExceptionHandler(value = LoginException.class)
+    public ActionResult loginException(LoginException e) {
+        ActionResult result = ActionResult.fail(ActionResultCode.Fail.getCode(), e.getMessage());
+        result.setData(e.getData());
+        return result;
+    }
+
+    @ResponseBody
+    @ExceptionHandler(value = ImportException.class)
+    public ActionResult loginException(ImportException e) {
+        ActionResult result = ActionResult.fail(ActionResultCode.Fail.getCode(), e.getMessage());
+        return result;
+    }
+
+    /**
+     * 自定义异常内容返回
+     *
+     * @param e
+     * @return
+     */
+    @ResponseBody
+    @ExceptionHandler(value = DataException.class)
+    public ActionResult dataException(DataException e) {
+        ActionResult result = ActionResult.fail(ActionResultCode.Fail.getCode(), e.getMessage());
+        return result;
+    }
+
+    /**
+     * 租户数据库异常
+     *
+     * @param e
+     * @return
+     */
+    @ResponseBody
+    @ExceptionHandler(value = TenantDatabaseException.class)
+    public ActionResult<String> tenantDatabaseException(TenantDatabaseException e) {
+        String msg;
+        if(e.getMessage() == null){
+            if (configValueUtil.getMultiTenancyUrl().contains("https")) {
+                // https 官网提示
+                msg = MsgCode.LOG109.get();
+            } else {
+                msg = MsgCode.LOG110.get();
+            }
+        }else{
+            msg = e.getMessage();
+        }
+        return ActionResult.fail(ActionResultCode.Fail.getCode(), msg);
+    }
+
+    @ResponseBody
+    @ExceptionHandler(value = MethodArgumentNotValidException.class)
+    public ActionResult methodArgumentNotValidException(MethodArgumentNotValidException e) {
+        Map<String, String> map = new HashMap<>(16);
+        List<ObjectError> allErrors = e.getBindingResult().getAllErrors();
+        for (int i = 0; i < allErrors.size(); i++) {
+            String s = allErrors.get(i).getCodes()[0];
+            //用分割的方法得到字段名
+            String[] parts = s.split("\\.");
+            String part1 = parts[parts.length - 1];
+            map.put(part1, allErrors.get(i).getDefaultMessage());
+        }
+        String json = JSON.toJSONString(map);
+        ActionResult result = ActionResult.fail(ActionResultCode.ValidateError.getCode(), json);
+        return result;
+    }
+
+    @ResponseBody
+    @ExceptionHandler(value = WorkFlowException.class)
+    public ActionResult workFlowException(WorkFlowException e) {
+        if (e.getCode() == 200) {
+            List<Map<String, Object>> list = JsonUtil.getJsonToListMap(e.getMessage());
+            return ActionResult.success(list);
+        } else {
+            return ActionResult.fail(e.getMessage());
+        }
+    }
+
+    @ResponseBody
+    @ExceptionHandler(value = WxErrorException.class)
+    public ActionResult wxErrorException(WxErrorException e) {
+        return ActionResult.fail(e.getError().getErrorCode(), MsgCode.AD103.get());
+    }
+
+    @ResponseBody
+    @ExceptionHandler(value = ServletException.class)
+    public void exception(ServletException e) throws Exception {
+        log.error("系统异常:" + e.getMessage(), e);
+        throw new Exception();
+    }
+
+    @ResponseBody
+    @ExceptionHandler(value = Exception.class)
+    public ActionResult exception(Exception e) {
+        log.error("系统异常:" + e.getMessage(), e);
+        if(e instanceof ConnectDatabaseException || e.getCause() instanceof ConnectDatabaseException){
+            Throwable t = e;
+            if(e.getCause() instanceof ConnectDatabaseException){
+                t = e.getCause();
+            }
+            return ActionResult.fail(ActionResultCode.Fail.getCode(), t.getMessage());
+        }
+        return ActionResult.fail(ActionResultCode.Fail.getCode(), MsgCode.AD102.get());
+    }
+
+    /**
+     * 权限码异常
+     */
+    @ResponseBody
+    @ExceptionHandler(NotPermissionException.class)
+    public ActionResult<Void> handleNotPermissionException(NotPermissionException e) {
+        return ActionResult.fail(ActionResultCode.Fail.getCode(),  MsgCode.AD104.get());
+    }
+
+    /**
+     * 角色权限异常
+     */
+    @ResponseBody
+    @ExceptionHandler(NotRoleException.class)
+    public ActionResult<Void> handleNotRoleException(NotRoleException e) {
+        return ActionResult.fail(ActionResultCode.ValidateError.getCode(), MsgCode.AD104.get());
+    }
+
+    /**
+     * 认证失败
+     */
+    @ResponseBody
+    @ExceptionHandler(NotLoginException.class)
+    public ActionResult<Void> handleNotLoginException(NotLoginException e) {
+        return ActionResult.fail(ActionResultCode.SessionOverdue.getCode(), MsgCode.AD105.get());
+    }
+
+    /**
+     * 无效认证
+     */
+    @ResponseBody
+    @ExceptionHandler(SameTokenInvalidException.class)
+    public ActionResult<Void> handleIdTokenInvalidException(SameTokenInvalidException e) {
+        return ActionResult.fail(ActionResultCode.SessionOverdue.getCode(), MsgCode.AD106.get());
+    }
+
+    /**
+     * 覆盖默认的JSON响应
+     */
+    @Override
+    @RequestMapping
+    public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
+        HttpStatus status = getStatus(request);
+
+        if (status == HttpStatus.NOT_FOUND) {
+            return new ResponseEntity<>(status);
+        }
+        return super.error(request);
+    }
+
+}

+ 8 - 0
jnpf-datareport-univer-common/src/main/java/jnpf/properties/ReportProperties.java

@@ -0,0 +1,8 @@
+package jnpf.properties;
+
+
+public class ReportProperties {
+
+    public static final String PREFIX = "report";
+
+}

+ 206 - 0
jnpf-datareport-univer-common/src/main/java/jnpf/util/ChartUtil.java

@@ -0,0 +1,206 @@
+package jnpf.util;
+
+import jnpf.univer.chart.UniverChartField;
+import jnpf.univer.chart.UniverChartModel;
+import jnpf.univer.data.cell.UniverDataConfig;
+import jnpf.ureport.definition.value.AggregateType;
+import jnpf.ureport.definition.value.DatasetValue;
+import jnpf.ureport.utils.DataUtils;
+
+import java.math.BigDecimal;
+import java.util.*;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/9/10 下午3:18
+ */
+public class ChartUtil {
+
+    public static void chart(List<UniverChartModel> chartList, Map<String, List<Map<String, Object>>> dataListAll, List<UniverDataConfig> echartsList) {
+        for (UniverDataConfig model : echartsList) {
+            UniverChartModel chartModel = new UniverChartModel();
+            chartModel.setDrawingId(model.getDrawingId());
+            chartModel.setSubUnitId(model.getSubUnitId());
+            chartModel.setUnitId(model.getUnitId());
+            //数据
+            Set<String> datasetName = new HashSet<>();
+            String classifyNameField = model.getClassifyNameField();
+            model.setClassifyNameField(fieldName(classifyNameField, datasetName));
+
+            String seriesNameField = model.getSeriesNameField();
+            model.setSeriesNameField(fieldName(seriesNameField, datasetName));
+
+            String seriesDataField = model.getSeriesDataField();
+            model.setSeriesDataField(fieldName(seriesDataField, datasetName));
+
+            String maxField = model.getMaxField();
+            model.setMaxField(fieldName(maxField, datasetName));
+
+            List<Map<String, Object>> dataList = new ArrayList<>();
+            for (String dataName : datasetName) {
+                List<Map<String, Object>> data = dataListAll.get(dataName) != null ? dataListAll.get(dataName) : new ArrayList<>();
+                dataList.addAll(data);
+            }
+            UniverChartField chartField = chart(dataList, model);
+            chartModel.setField(chartField);
+            chartList.add(chartModel);
+        }
+    }
+
+    private static UniverChartField chart(List<Map<String, Object>> dataList, UniverDataConfig dataConfig) {
+        String classifyName = dataConfig.getClassifyNameField();
+        String seriesName = dataConfig.getSeriesNameField();
+        String seriesData = dataConfig.getSeriesDataField();
+        String maxField = dataConfig.getMaxField();
+        Map<Object, Map<Object, List<Object>>> chartDataMap = new HashMap<>();
+        Map<Object, List<Object>> maxDatMap = new HashMap<>();
+        for (int i = 0; i < dataList.size(); i++) {
+            Map<String, Object> data = dataList.get(i);
+            Object classify = data.get(classifyName);
+            if (classify == null) {
+                continue;
+            }
+            Object value = data.get(seriesData);
+            if (value == null) {
+                continue;
+            }
+            Object series = data.get(seriesName) != null ? data.get(seriesName) : "";
+            Map<Object, List<Object>> categoryMap = chartDataMap.get(series) != null ? chartDataMap.get(series) : new HashMap<>();
+            List<Object> valueList = categoryMap.get(classify) != null ? categoryMap.get(classify) : new ArrayList<>();
+            valueList.add(value);
+            categoryMap.put(classify, valueList);
+            chartDataMap.put(series, categoryMap);
+
+            Object max = data.get(maxField);
+            if (max != null) {
+                List<Object> maxData = maxDatMap.get(classify) != null ? maxDatMap.get(classify) : new ArrayList<>();
+                maxData.add(max);
+                maxDatMap.put(classify, maxData);
+            }
+        }
+        return chartData(chartDataMap, maxDatMap, dataConfig);
+    }
+
+    private static UniverChartField chartData(Map<Object, Map<Object, List<Object>>> seriesDataMap, Map<Object, List<Object>> maxDataMap, UniverDataConfig dataConfig) {
+        UniverChartField chartField = new UniverChartField();
+        List<String> seriesNameList = new ArrayList<>();
+        Map<Object, List<List<String>>> classifyMap = new HashMap<>();
+        List<Integer> maxCount = new ArrayList<>();
+        maxCount.add(0);
+        for (Object series : seriesDataMap.keySet()) {
+            seriesNameList.add(String.valueOf(series));
+            Map<Object, List<Object>> classifyNameMap = seriesDataMap.get(series);
+            for (Object classify : classifyNameMap.keySet()) {
+                List<List<String>> categroyList = new ArrayList<>();
+                if (classifyMap.get(classify) != null) {
+                    categroyList.addAll(classifyMap.get(classify));
+                }
+                List<Object> valueList = classifyNameMap.get(classify);
+                List<String> data = data(valueList, dataConfig);
+                for (int i = 0; i < data.size(); i++) {
+                    List<String> classifyData = new ArrayList<>();
+                    classifyData.add(data.get(i));
+                    categroyList.add(classifyData);
+                }
+                classifyMap.put(classify, categroyList);
+                maxCount.add(categroyList.size());
+            }
+        }
+        if (StringUtil.isNotEmpty(dataConfig.getSeriesNameField())) {
+            chartField.setSeriesNameField(seriesNameList);
+        }
+        List<String> maxFieldList = new ArrayList<>();
+        List<String> classifyNameList = new ArrayList<>();
+        for (Object classify : classifyMap.keySet()) {
+            classifyNameList.add(String.valueOf(classify));
+            List<Object> objects = maxDataMap.get(classify) != null ? maxDataMap.get(classify) : new ArrayList<>();
+            if (objects.isEmpty()) {
+                objects.add(new BigDecimal(0));
+            }
+            dataConfig.setSummaryType(AggregateType.max.name());
+            List<String> data = data(objects, dataConfig);
+            maxFieldList.add(data.get(0));
+        }
+        List<List<String>> seriesDataList = new ArrayList<>();
+        for (int i = 0; i < Collections.max(maxCount); i++) {
+            List<String> seriesData = new ArrayList<>();
+            for (int k = 0; k < classifyNameList.size(); k++) {
+                String category = classifyNameList.get(k);
+                List<List<String>> categoryList = classifyMap.get(category) != null ? classifyMap.get(category) : new ArrayList<>();
+                List<String> categoryData = categoryList.size() - 1 >= i ? categoryList.get(i) : new ArrayList<>();
+                String data = categoryData.size() > 0 ? categoryData.get(0) : "";
+                seriesData.add(data);
+            }
+            seriesDataList.add(seriesData);
+        }
+        chartField.setClassifyNameField(classifyNameList);
+        chartField.setSeriesDataField(seriesDataList);
+        if (StringUtil.isNotEmpty(dataConfig.getMaxField())) {
+            chartField.setMaxField(maxFieldList);
+        }
+        return chartField;
+    }
+
+    private static List<String> data(List<Object> list, UniverDataConfig dataConfig) {
+        List<String> result = new ArrayList<>();
+        if (list.isEmpty()) {
+            return result;
+        }
+        String chartType = AggregateType.value(dataConfig.getSummaryType()) != null ? dataConfig.getSummaryType() : AggregateType.select.name();
+        DatasetValue expr = new DatasetValue();
+        expr.setProperty(chartType);
+        AggregateType value = AggregateType.value(chartType);
+        List<Map<String, Object>> dataList = new ArrayList<>();
+        for (Object data : list) {
+            Map<String, Object> dataMap = new HashMap<>();
+            dataMap.put(chartType, data);
+            dataList.add(dataMap);
+        }
+        List<BigDecimal> bindDataList = DataUtils.dataList(expr, dataList);
+        switch (value) {
+            case sum:
+                result.add(bindDataList.stream().reduce(BigDecimal.ZERO, BigDecimal::add).doubleValue() + "");
+                break;
+            case avg:
+                BigDecimal sumDecimal = bindDataList.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
+                if (bindDataList.isEmpty()) {
+                    bindDataList.add(new BigDecimal(0));
+                }
+                result.add(sumDecimal.divide(new BigDecimal(bindDataList.size()), 8, BigDecimal.ROUND_HALF_UP).doubleValue() + "");
+                break;
+            case max:
+                if (bindDataList.isEmpty()) {
+                    bindDataList.add(new BigDecimal(0));
+                }
+                result.add(bindDataList.stream().reduce(bindDataList.get(0), BigDecimal::max).doubleValue() + "");
+                break;
+            case min:
+                if (bindDataList.isEmpty()) {
+                    bindDataList.add(new BigDecimal(0));
+                }
+                result.add(bindDataList.stream().reduce(bindDataList.get(0), BigDecimal::min).doubleValue() + "");
+                break;
+            case count:
+                result.add(list.size() + "");
+                break;
+            default:
+                for (Object data : list) {
+                    result.add(String.valueOf(data));
+                }
+                break;
+        }
+        return result;
+    }
+
+    private static String fieldName(String field, Set<String> datasetName) {
+        String fieldName = field;
+        if (StringUtil.isNotEmpty(fieldName)) {
+            String[] params = fieldName.split("\\.");
+            datasetName.add(params[0]);
+            fieldName = params.length == 2 ? params[1] : fieldName;
+        }
+        return fieldName;
+    }
+}

+ 26 - 0
jnpf-datareport-univer-common/src/main/java/jnpf/util/DeepCopy.java

@@ -0,0 +1,26 @@
+package jnpf.util;
+
+import java.io.*;
+import java.util.HashMap;
+
+public class DeepCopy {
+    public static <T> T deepCopyViaSerialization(T obj) {
+        try {
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream(bos);
+            oos.writeObject(obj);
+            oos.flush();
+
+            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+            ObjectInputStream ois = new ObjectInputStream(bis);
+            return (T) ois.readObject();
+        } catch (IOException | ClassNotFoundException e) {
+            throw new RuntimeException("深拷贝失败", e);
+        }
+    }
+
+    // 使用示例
+    HashMap<String, Object> originalMap = new HashMap<>();
+    HashMap<String, Object> deepCopyMap = deepCopyViaSerialization(originalMap);
+
+}

+ 134 - 0
jnpf-datareport-univer-common/src/main/java/jnpf/util/ImageUtil.java

@@ -0,0 +1,134 @@
+package jnpf.util;
+
+import cn.hutool.core.util.RandomUtil;
+import com.google.common.collect.ImmutableList;
+import jnpf.enums.ImageEnum;
+import jnpf.univer.data.resource.UniverDrawing;
+import jnpf.univer.data.resource.UniverTransform;
+import jnpf.univer.properties.*;
+import jnpf.univer.zxing.UniverZxingModel;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ImageUtil {
+
+    public static UniverProperties zxing(UniverZxingModel zxingModel) {
+        String base64 = ZxingUtil.zxing(zxingModel);
+        return properties(base64, zxingModel.getUniverWidth(), zxingModel.getUniverHeight());
+    }
+
+    private static UniverProperties properties(String base64, int width, int height) {
+        String drawingId = RandomUtil.randomString(10);
+        UniverProperties properties = new UniverProperties();
+        properties.setId("d");
+        documentStyle(properties, width, height);
+        body(properties, drawingId);
+        drawings(properties, drawingId, base64, width, height);
+        List<String> drawingsOrder = ImmutableList.of(drawingId);
+        properties.setDrawingsOrder(drawingsOrder);
+        return properties;
+    }
+
+    private static void documentStyle(UniverProperties properties, int width, int height) {
+        UniverDocumentStyle documentStyle = new UniverDocumentStyle();
+        UniverDocumentStyleConfig pageSize = new UniverDocumentStyleConfig();
+        pageSize.setWidth(width);
+        pageSize.setHeight(height);
+        documentStyle.setPageSize(pageSize);
+        documentStyle.setMarginTop(0);
+        documentStyle.setMarginBottom(2);
+        documentStyle.setMarginRight(2);
+        documentStyle.setMarginLeft(2);
+
+        UniverDocumentStyleConfig renderConfig = new UniverDocumentStyleConfig();
+        renderConfig.setHorizontalAlign(0);
+        renderConfig.setVerticalAlign(0);
+        renderConfig.setCenterAngle(0);
+        renderConfig.setVertexAngle(0);
+        renderConfig.setWrapStrategy(0);
+        renderConfig.setZeroWidthParagraphBreak(1);
+        documentStyle.setRenderConfig(renderConfig);
+        properties.setDocumentStyle(documentStyle);
+    }
+
+    private static void body(UniverProperties properties, String drawingId) {
+        UniverBody body = new UniverBody();
+        body.setDataStream("\b\r\n");
+        body.setTextRuns(new ArrayList<>());
+        List<UniverBodyConfig> paragraphs = new ArrayList<>();
+        UniverBodyConfig config = new UniverBodyConfig();
+        config.setStartIndex(1);
+        UniverBodyConfig paragraphStyle = new UniverBodyConfig();
+        paragraphStyle.setHorizontalAlign(0);
+        config.setParagraphStyle(paragraphStyle);
+        paragraphs.add(config);
+        body.setParagraphs(paragraphs);
+
+        List<UniverBodyConfig> sectionBreaks = new ArrayList<>();
+        UniverBodyConfig section = new UniverBodyConfig();
+        section.setStartIndex(2);
+        sectionBreaks.add(section);
+        body.setSectionBreaks(sectionBreaks);
+
+        List<UniverBodyConfig> customBlocks = new ArrayList<>();
+        UniverBodyConfig custom = new UniverBodyConfig();
+        custom.setStartIndex(0);
+        custom.setBlockId(drawingId);
+        customBlocks.add(custom);
+        body.setCustomBlocks(customBlocks);
+        body.setCustomRanges(new ArrayList<>());
+        body.setCustomDecorations(new ArrayList<>());
+
+        properties.setBody(body);
+    }
+
+    private static void drawings(UniverProperties properties, String drawingId, String base64, int width, int height) {
+        UniverDrawing drawing = new UniverDrawing();
+        drawing.setUnitId("d");
+        drawing.setSubUnitId("d");
+        drawing.setDrawingId(drawingId);
+        drawing.setDrawingType(0);
+        drawing.setImageSourceType(ImageEnum.BASE64.name());
+        drawing.setSource(base64);
+
+        UniverTransform transform = new UniverTransform();
+        transform.setLeft(0);
+        transform.setTop(0);
+        transform.setWidth(width);
+        transform.setHeight(height);
+        drawing.setTransform(transform);
+
+        UniverTransform docTransform = new UniverTransform();
+        UniverTransform size = new UniverTransform();
+        size.setWidth(width);
+        size.setHeight(height);
+        docTransform.setSize(size);
+        UniverTransform positionH = new UniverTransform();
+        positionH.setRelativeFrom(0);
+        positionH.setPosOffset(0);
+        docTransform.setPositionH(positionH);
+        UniverTransform positionV = new UniverTransform();
+        positionV.setRelativeFrom(1);
+        positionV.setPosOffset(0);
+        docTransform.setPositionV(positionV);
+        docTransform.setAngle(0);
+        drawing.setDocTransform(docTransform);
+
+        drawing.setBehindDoc(0);
+        drawing.setTitle("");
+        drawing.setDescription("");
+        drawing.setLayoutType(0);
+        drawing.setWrapText(0);
+        drawing.setDistB(0);
+        drawing.setDistL(0);
+        drawing.setDistR(0);
+        drawing.setDistT(0);
+
+        Map<String, UniverDrawing> drawings = new HashMap<>();
+        drawings.put(drawingId, drawing);
+        properties.setDrawings(drawings);
+    }
+}

+ 95 - 0
jnpf-datareport-univer-common/src/main/java/jnpf/util/ReportUtil.java

@@ -0,0 +1,95 @@
+package jnpf.util;
+
+import cn.hutool.core.lang.TypeReference;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import cn.hutool.http.Method;
+import cn.hutool.json.JSONUtil;
+import jnpf.base.ActionResult;
+import jnpf.base.UserInfo;
+import jnpf.consts.ApiConst;
+import jnpf.database.util.TenantDataSourceUtil;
+import jnpf.model.login.MeInfoVO;
+import jnpf.model.tenant.TenantVO;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * 报表工具类
+ */
+@Slf4j
+public class ReportUtil {
+
+    public static UserInfo initUserInfo(String token) {
+        UserInfo userInfo = UserProvider.getLocalLoginUser();
+        if (userInfo == null) {
+            try {
+                HttpResponse response = HttpRequest.get(ApiConst.ME).header(Constants.AUTHORIZATION, token).execute();
+                if (response.isOk()) {
+                    String result = response.body();
+                    try {
+                        ActionResult<MeInfoVO> out = JSONUtil.toBean(result, new TypeReference<ActionResult<MeInfoVO>>() {
+                        }, false);
+                        if (Objects.equals(out.getCode(), Constants.SUCCESS)) {
+                            MeInfoVO meInfoVO = out.getData();
+                            if (StringUtil.isNotEmpty(meInfoVO.getUserId())) {
+                                // 构造用户信息
+                                String tenantId = meInfoVO.getTenantId();
+                                userInfo = new UserInfo();
+                                userInfo.setId(meInfoVO.getUserId());
+                                userInfo.setUserId(meInfoVO.getUserId());
+                                userInfo.setUserName(meInfoVO.getUserName());
+                                userInfo.setUserAccount(meInfoVO.getUserAccount());
+                                userInfo.setTenantId(tenantId);
+                                UserProvider.setLocalLoginUser(userInfo);
+                                // 设置租户信息
+                                if (TenantDataSourceUtil.isMultiTenancy()) {
+                                    // 直接从租户系统获取租户信息
+                                    TenantVO tenantVO = TenantDataSourceUtil.getRemoteTenantInfo(tenantId);
+                                    TenantDataSourceUtil.switchTenant(tenantId, tenantVO);
+                                    userInfo.setTenantDbType(tenantVO.getType());
+                                    userInfo.setTenantDbConnectionString(tenantVO.getDbName());
+                                }
+                                return userInfo;
+                            }
+                            if (log.isDebugEnabled()) {
+                                log.debug("获取用户信息: {}", result);
+                            }
+                        }else{
+                            log.error("主系统未成功返回用户信息: {}", out);
+                        }
+                    } catch (Exception e) {
+                        log.error("用户信息解析失败:" + result, e);
+                    }
+                }
+            } catch (Exception e) {
+                log.error("获取用户信息错误: {}", e.getMessage());
+            }
+        }
+        return userInfo;
+    }
+
+    public static String http(String url, Method method, Map<String, Object> params) {
+        HttpRequest request = HttpRequest.of(url).method(method);
+        switch (method){
+            case GET:
+                request.form(params);
+                break;
+            default:
+                request.body(JsonUtil.getObjectToString(params));
+                break;
+        }
+        request.header(Constants.AUTHORIZATION, UserProvider.getToken());
+        request.setConnectionTimeout(50000);
+        request.setReadTimeout(60000);
+        String json = "{}";
+        try {
+            json = request.execute().body();
+        } catch (Exception e) {
+            log.error(e.getMessage());
+        }
+        return json;
+    }
+}

+ 2471 - 0
jnpf-datareport-univer-common/src/main/java/jnpf/util/UniverConvert.java

@@ -0,0 +1,2471 @@
+package jnpf.util;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.collection.ListUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.google.common.collect.ImmutableList;
+import jnpf.constant.DataInterfaceVarConst;
+import jnpf.constant.MsgCode;
+import jnpf.enums.*;
+import jnpf.exception.DataException;
+import jnpf.model.*;
+import jnpf.univer.chart.UniverChartModel;
+import jnpf.univer.data.cell.UniverDataConfig;
+import jnpf.univer.data.custom.UniverCustom;
+import jnpf.univer.data.resource.UniverDrawing;
+import jnpf.univer.model.UniverPreview;
+import jnpf.univer.model.UniverWorkBook;
+import jnpf.univer.properties.UniverBody;
+import jnpf.univer.properties.UniverBodyConfig;
+import jnpf.univer.properties.UniverProperties;
+import jnpf.univer.resources.UniverResource;
+import jnpf.univer.resources.UniverResourceData;
+import jnpf.univer.sheet.*;
+import jnpf.univer.zxing.UniverZxingModel;
+import jnpf.ureport.build.Dataset;
+import jnpf.ureport.build.ReportBuilder;
+import jnpf.ureport.cell.down.DownCellbuilder;
+import jnpf.ureport.cell.right.RightCellbuilder;
+import jnpf.ureport.definition.*;
+import jnpf.ureport.definition.value.AggregateType;
+import jnpf.ureport.definition.value.DatasetValue;
+import jnpf.ureport.definition.value.SimpleValue;
+import jnpf.ureport.definition.value.Value;
+import jnpf.ureport.model.*;
+import jnpf.ureport.utils.DataUtils;
+import jnpf.util.type.SortType;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.CellReference;
+import org.jetbrains.annotations.NotNull;
+
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/5/11 下午4:35
+ */
+public class UniverConvert {
+    public static final int OFFSET = 0;
+    public static final Set<String> SIMPLE_VALUE = Set.of(
+            CellDataEnum.text.name(),
+            CellDataEnum.parameter.name()
+    );
+
+
+    //-------------------------------------解析数据------------------------------------------------
+
+    public UniverPreview transform(String snapshot, String cells, String sort, String fence, Map<String, Map<String, List<Map<String, Object>>>> sheetData, Map<String, Map<String, Map<String, Object>>> parameterData) {
+        UniverWorkBook univerWorkBook = StringUtil.isNotEmpty(snapshot) ? JsonUtil.getJsonToBean(snapshot, UniverWorkBook.class) : new UniverWorkBook();
+        String unitId = RandomUtil.uuId();
+        univerWorkBook.setId(unitId);
+        UniverCustom custom = StringUtil.isNotEmpty(cells) ? JsonUtil.getJsonToBean(cells, UniverCustom.class) : new UniverCustom();
+        List<DataQuery> sortListAll = StringUtil.isNotEmpty(sort) ? JsonUtil.getJsonToList(sort, DataQuery.class) : new ArrayList<>();
+        List<Fence> fenceListAll = StringUtil.isNotEmpty(fence) ? JsonUtil.getJsonToList(fence, Fence.class) : new ArrayList<>();
+        //排序
+        Map<String, Map<String, List<DataSortModel>>> sortMap = new HashMap<>();
+        for (DataQuery dataQuery : sortListAll) {
+            String sheetId = dataQuery.getSheet();
+            Map<String, List<DataSortModel>> dataBaseMap = sortMap.get(sheetId) != null ? sortMap.get(sheetId) : new HashMap<>();
+            List<DataSortModel> sortList = dataQuery.getSortList();
+            for (DataSortModel dataModel : sortList) {
+                DataSortModel sortModel = JsonUtil.getJsonToBean(dataModel, DataSortModel.class);
+                String[] params = sortModel.getVModel().split("\\.");
+                if (params.length == 2) {
+                    String datasetName = params[0];
+                    String property = params[1];
+                    sortModel.setVModel(property);
+                    List<DataSortModel> dataSortModels = dataBaseMap.get(datasetName) != null ? dataBaseMap.get(datasetName) : new ArrayList<>();
+                    dataSortModels.add(sortModel);
+                    dataBaseMap.put(datasetName, dataSortModels);
+                }
+            }
+            sortMap.put(sheetId, dataBaseMap);
+        }
+        Map<String, ColumnList> fenceMap = new HashMap<>();
+        for (Fence fenceEntity : fenceListAll) {
+            String sheetId = fenceEntity.getSheet();
+            ColumnList columnList = fenceEntity.getColumnList();
+            fenceMap.put(sheetId, columnList);
+        }
+
+        //悬浮图表
+        List<UniverResource> resources = univerWorkBook.getResources() != null ? univerWorkBook.getResources() : new ArrayList<>();
+        Map<String, UniverDataConfig> floatEcharts = custom.getFloatEcharts() != null ? custom.getFloatEcharts() : new HashMap<>();
+        Map<String, List<UniverDataConfig>> floatEchartMap = floatEchart(univerWorkBook.getId(), resources, floatEcharts);
+        //单元格图表
+        Map<String, UniverDataConfig> cellEcharts = custom.getCellEcharts() != null ? custom.getCellEcharts() : new HashMap<>();
+        Map<String, List<UniverDataConfig>> cellEchartMap = cellEchart(cellEcharts, univerWorkBook.getId());
+        Map<String, UniverSheet> sheetMap = new HashMap<>();
+        List<UniverChartModel> chartList = new ArrayList<>();
+        for (String sheetOrder : univerWorkBook.getSheetOrder()) {
+            UniverSheet univerSheet = univerWorkBook.getSheets().get(sheetOrder);
+            Map<String, List<Map<String, Object>>> dataList = sheetData.get(sheetOrder) != null ? sheetData.get(sheetOrder) : new HashMap<>();
+            Map<String, List<DataSortModel>> sortDataMap = sortMap.get(sheetOrder) != null ? sortMap.get(sheetOrder) : new HashMap<>();
+            Map<String, Map<String, Object>> parameterMap = parameterData.get(sheetOrder) != null ? parameterData.get(sheetOrder) : new HashMap<>();
+            if (ObjectUtil.isNotEmpty(univerSheet)) {
+                List<UniverDataConfig> cellList = custom.getCells().stream().filter(t -> Objects.equals(sheetOrder, t.getSheet())).collect(Collectors.toList());
+                List<UniverDataConfig> cellEchartList = cellEchartMap.get(sheetOrder) != null ? cellEchartMap.get(sheetOrder) : new ArrayList<>();
+                cellList.addAll(cellEchartList);
+                ColumnList columnList = fenceMap.get(sheetOrder) != null ? fenceMap.get(sheetOrder) : new ColumnList();
+                Map<String, List<Map<String, Object>>> oneDataList = new HashMap<>();
+                Map<String, String> sortInMap = new HashMap<>();
+                for (String key : dataList.keySet()) {
+                    List<Map<String, Object>> list = dataList.get(key) != null ? dataList.get(key) : new ArrayList<>();
+                    List<DataSortModel> dataSortList = sortDataMap.get(key) != null ? sortDataMap.get(key) : new ArrayList<>();
+                    StringJoiner joiner = new StringJoiner(",");
+                    for (DataSortModel dataSortModel : dataSortList) {
+                        String vModel = dataSortModel.getVModel();
+                        boolean isDesc = Objects.equals(SortType.DESC, dataSortModel.getType());
+                        joiner.add((isDesc ? "-" : "") + vModel);
+                    }
+                    sortInMap.put(key, joiner.toString());
+                    List<Map<String, Object>> data = DataUtils.orderDataList(list, joiner.toString());
+
+                    oneDataList.put(key, data);
+                }
+                UniverSheet sheet = new UniverSheet();
+
+
+                sheet = buildLuckySheetDate(univerSheet, cellList, oneDataList, columnList, parameterMap, resources, sortInMap);
+//                if (BeanUtil.isNotEmpty(columnList) && columnList.isColumnState()) {
+//                    //函数处理
+//                    Map<Integer, Map<Integer, UniverSheetCellData>> sheetCellData = sheet.getCellData();
+//                    //map转大集合
+//                    List<UniverSheetCellData> resultList = sheetCellData.values().stream()
+//                            .flatMap(innerMap -> innerMap.values().stream())
+//                            .filter(item -> null != item.getT() && item.getT().equals(CellDataTypeEnum.Formula.getCode()))
+//                            .collect(Collectors.toList());
+//                    for (UniverSheetCellData univerSheetCellData : resultList) {
+//                        formulaListOut(univerSheetCellData, sheetCellData, columnList.getColumnStyle());
+//                    }
+//
+//
+//                }
+
+
+                List<UniverDataConfig> echartsList = new ArrayList<>();
+                echartsList.addAll(floatEchartMap.get(sheetOrder) != null ? floatEchartMap.get(sheetOrder) : new ArrayList<>());
+                echartsList.addAll(cellEchartList);
+                ChartUtil.chart(chartList, dataList, echartsList);
+
+                sheetMap.put(sheet.getId(), sheet);
+            }
+        }
+        univerWorkBook.setSheets(sheetMap);
+        UniverPreview vo = new UniverPreview();
+        vo.setSnapshot(JSON.toJSONString(JSON.toJSON(univerWorkBook)));
+        vo.setCells(cells);
+
+        vo.setChartData(JSON.toJSONString(JSON.toJSON(chartList)));
+        return vo;
+    }
+
+
+    private UniverSheet buildLuckySheetDate(UniverSheet sheet, List<UniverDataConfig> cell, Map<String, List<Map<String, Object>>> stringListMap,
+                                            ColumnList columnList, Map<String, Map<String, Object>> parameterDataMap
+            , List<UniverResource> resources, Map<String, String> sortInMap) {
+        Map<Integer, Map<Integer, UniverSheetCellData>> cellData = sheet.getCellData();
+        List<UniverDataConfig> parameterData = cell.stream().filter(t -> CellDataEnum.parameter.name().equals(t.getType())).collect(Collectors.toList());
+        Pattern pattern = Pattern.compile("#\\{(.*?)\\}");
+        for (UniverDataConfig dataConfig : parameterData) {
+            Integer row = dataConfig.getRow();
+            Integer col = dataConfig.getCol();
+            Map<Integer, UniverSheetCellData> dataMap = cellData.get(row) != null ? cellData.get(row) : new HashMap<>();
+            UniverSheetCellData sheetCellData = dataMap.get(col);
+            if (sheetCellData != null) {
+                String value = "";
+                Object v = sheetCellData.getV();
+                if (v != null) {
+                    value = v + "";
+                }
+                Object p = sheetCellData.getP();
+                if (p != null) {
+                    UniverProperties properties = JsonUtil.getJsonToBean(p, UniverProperties.class);
+                    UniverBody body = properties.getBody();
+                    if (body != null) {
+                        String dataStream = body.getDataStream();
+                        if (dataStream != null) {
+                            value = dataStream;
+                        }
+                    }
+                }
+                Matcher matcher = pattern.matcher(value);
+                Map<Integer, Map<Integer, String>> number = new HashMap<>();
+                List<String> random = ImmutableList.of(DataInterfaceVarConst.ID_LOT);
+                while (matcher.find()) {
+                    String patternText = matcher.group(1);
+                    String[] split = patternText.split("\\.");
+                    String datasetName = split[0];
+                    String property = split.length > 1 ? split[1] : split[0];
+                    boolean isRandom = random.contains(property);
+                    Map<String, Object> data = parameterDataMap.get(datasetName) != null ? parameterDataMap.get(datasetName) : new HashMap<>();
+                    String textValue = data.get(property) != null ? data.get(property) + "" : isRandom ? RandomUtil.uuId() : "";
+                    Map<Integer, String> name = new HashMap<>();
+                    name.put(matcher.end(), textValue);
+                    number.put(matcher.start(), name);
+                }
+                List<Integer> colList = new ArrayList<>(number.keySet()).stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
+                for (Integer start : colList) {
+                    Map<Integer, String> name = number.get(start);
+                    for (Integer end : name.keySet()) {
+                        value = value.substring(0, start) + name.get(end) + value.substring(end, value.length());
+                    }
+                }
+                sheetCellData.setV(value);
+                sheetCellData.setP(null);
+            }
+        }
+        List<UniverDataConfig> datasourceData = cell.stream().filter(t -> CellDataEnum.dataSource.name().equals(t.getType())).collect(Collectors.toList());
+        if (datasourceData.isEmpty()) {
+            return sheet;
+        }
+        List<Integer> rowMax = new ArrayList<>();
+        rowMax.add(0);
+        List<Integer> columnMax = new ArrayList<>();
+        columnMax.add(0);
+        for (Integer rowKey : cellData.keySet()) {
+            rowMax.add(rowKey);
+            Map<Integer, UniverSheetCellData> cellDataMap = cellData.get(rowKey);
+            columnMax.addAll(cellDataMap.keySet());
+        }
+        List<UniverSheetRange> mergeData = sheet.getMergeData();
+        Map<Integer, UniverSheetRowData> sheetRowData = sheet.getRowData();
+        Map<Integer, UniverSheetColumnData> sheetColumnData = sheet.getColumnData();
+        ReportDefinition reportDefinition = new ReportDefinition();
+        List<RowDefinition> rows = new ArrayList<>();
+        List<ColumnDefinition> columns = new ArrayList<>();
+        List<CellDefinition> cells = new ArrayList<>();
+        Map<Integer, Map<Integer, Integer>> fillRowMap = new HashMap<>();
+        reportDefinition.setRows(rows);
+        reportDefinition.setColumns(columns);
+        reportDefinition.setCells(cells);
+        Map<String, Dataset> datasetMap = new HashMap<>();
+        for (String key : stringListMap.keySet()) {
+            Dataset dataset = new Dataset();
+            dataset.setName(key);
+            dataset.setData(stringListMap.get(key));
+            datasetMap.put(key, dataset);
+        }
+
+        reportDefinition.setDatasetMap(datasetMap);
+        Map<String, Formula> formulaMap = new HashMap<>();
+        //冻结
+        UniverSheetFreeze freeze = sheet.getFreeze() != null ? sheet.getFreeze() : new UniverSheetFreeze();
+        int freezeRow = freeze.getStartRow();
+        int freezeColumn = freeze.getStartColumn();
+
+        zhouTest(sheet, cell, rowMax, sheetRowData, freezeRow, cellData, columnMax, sheetColumnData,
+                freezeColumn, mergeData, formulaMap, cells, columns, fillRowMap, rows);
+        Map<String, Integer> fillBlankRowsMap = fillEmptyRows(fillRowMap);
+        reportDefinition.setFillBlankRowsMap(fillBlankRowsMap);
+        rebuild(reportDefinition);
+
+        rebuildReportDefinition(reportDefinition);
+
+        ReportBuilder reportBuilder = new ReportBuilder();
+
+        Map<String, Map<Integer, Map<Integer, String>>> nameMap = new HashMap<>();
+        Report report = reportBuilder.buildReport(reportDefinition, sortInMap);
+        UniverSheet result = sheet(sheet, report, formulaMap, columnList, nameMap);
+        resource(sheet.getId(), nameMap, resources);
+        return result;
+    }
+
+
+    private static void zhouTest(UniverSheet sheet, List<UniverDataConfig> cell, List<Integer> rowMax, Map<Integer, UniverSheetRowData> sheetRowData
+            , int freezeRow, Map<Integer, Map<Integer, UniverSheetCellData>> cellData, List<Integer> columnMax, Map<Integer, UniverSheetColumnData> sheetColumnData
+            , int freezeColumn, List<UniverSheetRange> mergeData, Map<String, Formula> formulaMap, List<CellDefinition> cells, List<ColumnDefinition> columns
+            , Map<Integer, Map<Integer, Integer>> fillRowMap, List<RowDefinition> rows) {
+        for (int i = 0; i <= Collections.max(rowMax); i++) {
+            UniverSheetRowData rowData = sheetRowData.get(i);
+            RowDefinition rowDefinition = new RowDefinition();
+            rowDefinition.setRowNumber(i);
+            rowDefinition.setSheetRowData(rowData);
+            rowDefinition.setFreeze(Objects.equals(freezeRow - 1, i));
+            Map<Integer, UniverSheetCellData> columnDataMap = cellData.get(i) != null ? cellData.get(i) : new HashMap<>();
+            for (int j = 0; j <= Collections.max(columnMax); j++) {
+                UniverSheetColumnData columnData = sheetColumnData.get(j);
+                ColumnDefinition columnDefinition = new ColumnDefinition();
+                columnDefinition.setColumnNumber(j);
+                columnDefinition.setFreeze(Objects.equals(freezeColumn - 1, j));
+                columnDefinition.setSheetColumnData(columnData);
+                UniverSheetCellData sheetCellData = columnDataMap.get(j) != null ? columnDataMap.get(j) : new UniverSheetCellData();
+                //合并
+                int rowSpan = 0;
+                int colSpan = 0;
+                StyleModel styleModel = new StyleModel();
+                UniverSheetRange sheetRange = mergeData.stream().filter(t -> t.getStartRow().equals(rowDefinition.getRowNumber()) && t.getStartColumn().equals(columnDefinition.getColumnNumber())).findFirst().orElse(null);
+                boolean isRange = sheetRange != null;
+                if (isRange) {
+                    rowSpan = sheetRange.getEndRow() - sheetRange.getStartRow();
+                    colSpan = sheetRange.getEndColumn() - sheetRange.getStartColumn();
+                    if (rowSpan > 0) {
+                        for (int row = sheetRange.getStartRow() + 1; row <= sheetRange.getEndRow() - 1; row++) {
+                            Map<Integer, UniverSheetCellData> dataMap = cellData.get(row);
+                            if (dataMap != null) {
+                                UniverSheetCellData startData = dataMap.get(sheetRange.getStartColumn());
+                                if (startData != null) {
+                                    styleModel.setL(startData.getS());
+                                }
+                                UniverSheetCellData endData = dataMap.get(sheetRange.getEndColumn());
+                                if (endData != null) {
+                                    styleModel.setR(endData.getS());
+                                }
+                            }
+                        }
+                    }
+                    if (colSpan > 0) {
+                        Map<Integer, UniverSheetCellData> startDataMap = cellData.get(sheetRange.getStartRow());
+                        Map<Integer, UniverSheetCellData> endDataMap = cellData.get(sheetRange.getEndRow());
+                        for (int col = sheetRange.getStartColumn() + 1; col <= sheetRange.getEndColumn() - 1; col++) {
+                            if (startDataMap != null) {
+                                UniverSheetCellData startData = startDataMap.get(col);
+                                if (startData != null) {
+                                    styleModel.setT(startData.getS());
+                                }
+                            }
+                            if (endDataMap != null) {
+                                UniverSheetCellData endData = endDataMap.get(col);
+                                if (endData != null) {
+                                    styleModel.setB(endData.getS());
+                                }
+                            }
+                        }
+                    }
+                    Map<Integer, UniverSheetCellData> startDataMap = cellData.get(sheetRange.getStartRow());
+                    if (startDataMap != null) {
+                        UniverSheetCellData leftTopData = startDataMap.get(sheetRange.getStartColumn());
+                        if (leftTopData != null) {
+                            styleModel.setLt(leftTopData.getS());
+                        }
+                        UniverSheetCellData rightTopData = startDataMap.get(sheetRange.getEndColumn());
+                        if (rightTopData != null) {
+                            styleModel.setRt(rightTopData.getS());
+                        }
+                    }
+                    Map<Integer, UniverSheetCellData> endDataMap = cellData.get(sheetRange.getEndRow());
+                    if (endDataMap != null) {
+                        UniverSheetCellData leftBodData = endDataMap.get(sheetRange.getStartColumn());
+                        if (leftBodData != null) {
+                            styleModel.setLb(leftBodData.getS());
+                        }
+                        UniverSheetCellData rightBodData = endDataMap.get(sheetRange.getEndColumn());
+                        if (rightBodData != null) {
+                            styleModel.setRb(rightBodData.getS());
+                        }
+                    }
+                }
+                CellDefinition cellDefinition = new CellDefinition();
+                String definitionName = new CellReference(i, j).formatAsString();
+                cellDefinition.setName(definitionName);
+                cellDefinition.setRowNumber(i + 1);
+                cellDefinition.setColumnNumber(j + 1);
+                cellDefinition.setRowSpan(rowSpan > 0 ? rowSpan + 1 : rowSpan);
+                cellDefinition.setColSpan(colSpan > 0 ? colSpan + 1 : colSpan);
+                cellDefinition.setSheetColumnData(columnData);
+                cellDefinition.setSheetRowData(rowData);
+                cellDefinition.setCellData(sheetCellData);
+                cellDefinition.setStyleModel(styleModel);
+
+                //判断函数
+                String formulaValue = sheetCellData.getF() != null ? sheetCellData.getF() : "";
+                if (StringUtil.isNotEmpty(formulaValue)) {
+                    if (formulaValue.startsWith("=")) {
+                        List<CellRangeAddress> list = new ArrayList<>();
+                        formulaName(formulaValue, list);
+                        Map<Integer, Map<Integer, String>> formulaCell = new HashMap<>();
+                        for (CellRangeAddress rangeAddress : list) {
+                            int startRow = rangeAddress.getFirstRow();
+                            int startCol = rangeAddress.getFirstColumn();
+                            int endRow = rangeAddress.getLastRow();
+                            int endCol = rangeAddress.getLastColumn();
+                            List<CellReference> cellsRange = getCellsRange(startRow, endRow, startCol, endCol);
+                            List<String> rangeName = new ArrayList<>();
+                            for (CellReference reference : cellsRange) {
+                                int row = reference.getRow();
+                                int col = reference.getCol();
+                                Map<Integer, String> rowMap = formulaCell.get(row) != null ? formulaCell.get(row) : new HashMap<>();
+                                rowMap.put(col, reference.formatAsString());
+                                formulaCell.put(row, rowMap);
+                                rangeName.add(reference.formatAsString());
+                            }
+                            if (cellsRange.size() > 1) {
+                                formulaValue = formulaValue.replace(rangeAddress.formatAsString(), String.join(",", rangeName));
+                            }
+                        }
+                        List<String> cellNameList = new ArrayList<>();
+                        List<Integer> rowList = new ArrayList<>(formulaCell.keySet()).stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
+                        for (Integer row : rowList) {
+                            Map<Integer, String> rowMap = formulaCell.get(row) != null ? formulaCell.get(row) : new HashMap<>();
+                            List<Integer> colList = new ArrayList<>(rowMap.keySet()).stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
+                            for (Integer col : colList) {
+                                cellNameList.add(rowMap.get(col));
+                            }
+                        }
+                        Formula formula = new Formula();
+                        formula.setFormula(formulaValue);
+                        formula.setName(definitionName);
+                        formula.setCellNameList(cellNameList);
+                        formulaMap.put(definitionName, formula);
+                        sheetCellData.setF(formulaValue);
+                        sheetCellData.setV(null);
+                    }
+                }
+                //数据类型
+                Expand expand = Expand.None;
+                UniverDataConfig univerCellData = cell.stream().filter(t -> Objects.equals(t.getRow(), rowDefinition.getRowNumber()) && Objects.equals(t.getCol(), columnDefinition.getColumnNumber())).findFirst().orElse(new UniverDataConfig());
+                UniverDataConfig univerDataConfig = univerCellData.getCustom() != null ? univerCellData.getCustom() : new UniverDataConfig();
+                String cellType = univerCellData.getType();
+                cellDefinition.setType(cellType);
+                String value = sheetCellData.getV() != null && SIMPLE_VALUE.contains(cellType) ? sheetCellData.getV().toString() : "";
+                Value values = new SimpleValue(value);
+                if (Objects.equals(CellDataEnum.dataSource.name(), cellType)) {
+                    String datasetName = "";
+                    String property = "";
+                    String fillDirection = univerDataConfig.getFillDirection();
+                    String fileName = univerDataConfig.getField();
+                    String summaryType = univerDataConfig.getSummaryType();
+                    if (StringUtils.isNotEmpty(fileName)) {
+                        String[] params = fileName.split("\\.");
+                        if (params.length == 2) {
+                            datasetName = params[0];
+                            property = params[1];
+                        }
+                    }
+                    String displayType = univerDataConfig.getDisplayType();
+                    boolean isQrCode = Objects.equals(ZxingEnum.QRCODE.getType(), displayType);
+                    UniverZxingModel qrcode = univerDataConfig.getQrCodeOption();
+                    UniverSheetRange range = new UniverSheetRange();
+                    range.setStartRow(i);
+                    range.setEndRow(i);
+                    range.setStartColumn(j);
+                    range.setEndColumn(j);
+                    UniverZxingModel zxingModel = ZxingUtil.zxingImage(sheetRowData, sheetColumnData, sheet, isRange ? sheetRange : range, displayType);
+                    zxingModel.setDisplayType(displayType);
+                    if (isQrCode && qrcode != null && qrcode.getColor() != null) {
+                        UniverZxingModel color = qrcode.getColor();
+                        zxingModel.setBackground(color.getLight());
+                        zxingModel.setLineColor(color.getDark());
+                        zxingModel.setErrorCorrectionLevel(qrcode.getErrorCorrectionLevel());
+                        cellDefinition.setZxing(zxingModel);
+                    }
+                    UniverZxingModel jsbarCode = univerDataConfig.getJsbarCodeOption();
+                    boolean isBarCode = Objects.equals(ZxingEnum.BARCODE.getType(), displayType);
+                    if (isBarCode && jsbarCode != null) {
+                        zxingModel.setBackground(jsbarCode.getBackground());
+                        zxingModel.setLineColor(jsbarCode.getLineColor());
+                        zxingModel.setFormat(jsbarCode.getFormat());
+                        cellDefinition.setZxing(zxingModel);
+                    }
+                    AggregateType aggregate = AggregateType.none;
+                    Integer type = univerDataConfig.getPolymerizationType();
+                    boolean isSelect = Objects.equals(type, UniverDataEnum.select.getCode());
+                    boolean isGroup = Objects.equals(type, UniverDataEnum.group.getCode());
+                    boolean isSummary = Objects.equals(type, UniverDataEnum.summary.getCode());
+                    if (isSelect || isGroup) {
+                        expand = Objects.equals(UniverDataEnum.cellDirection.getName(), fillDirection) ? Expand.Down : Expand.Right;
+                        aggregate = isGroup ? AggregateType.group : AggregateType.select;
+                    } else if (isSummary) {
+                        aggregate = AggregateType.value(summaryType);
+                    }
+                    DatasetValue datasetValue = new DatasetValue();
+                    datasetValue.setDatasetName(datasetName);
+                    datasetValue.setProperty(property);
+                    datasetValue.setAggregate(aggregate);
+                    datasetValue.setGroupType(univerDataConfig.getGroupType());
+                    values = datasetValue;
+                }
+
+                String leftName = "";
+                String leftType = univerDataConfig.getLeftParentCellType();
+                if (StringUtil.isNotEmpty(leftType)) {
+                    UniverDataEnum dataType = UniverDataEnum.getData(leftType);
+                    if (dataType != null) {
+                        switch (dataType) {
+                            case cellNone:
+                                leftName = UniverDataEnum.cellRoot.getName();
+                                break;
+                            case cellCustom:
+                                leftName = univerDataConfig.getLeftParentCellCustomRowName() + univerDataConfig.getLeftParentCellCustomColName();
+                                break;
+                        }
+                    }
+                }
+                cellDefinition.setLeftType(leftType);
+                cellDefinition.setLeftParentCellName(leftName);
+                String topName = "";
+                String topType = univerDataConfig.getTopParentCellType();
+                if (StringUtil.isNotEmpty(topType)) {
+                    UniverDataEnum dataType = UniverDataEnum.getData(topType);
+                    if (dataType != null) {
+                        switch (dataType) {
+                            case cellNone:
+                                topName = UniverDataEnum.cellRoot.getName();
+                                break;
+                            case cellCustom:
+                                topName = univerDataConfig.getTopParentCellCustomRowName() + univerDataConfig.getTopParentCellCustomColName();
+                                break;
+                        }
+                    }
+                }
+                cellDefinition.setTopType(topType);
+                cellDefinition.setTopParentCellName(topName);
+                cellDefinition.setExpand(expand);
+                cellDefinition.setValue(values);
+                boolean notAdd = mergeData.stream().anyMatch(t -> t.getStartRow() <= rowDefinition.getRowNumber() && t.getStartColumn() <= columnDefinition.getColumnNumber() && t.getEndRow() >= rowDefinition.getRowNumber() && t.getEndColumn() >= columnDefinition.getColumnNumber());
+                if (!notAdd || isRange) {
+                    cells.add(cellDefinition);
+                }
+                columnDefinition.setColumnNumber(columnDefinition.getColumnNumber() + 1);
+                if (columns.stream().noneMatch(t -> Objects.equals(t.getColumnNumber(), columnDefinition.getColumnNumber()))) {
+                    columns.add(columnDefinition);
+                }
+                Boolean fillEmptyRows = univerDataConfig.getFillEmptyRows();
+                Integer fillEmptyNum = univerDataConfig.getFillEmptyNum();
+                if (fillEmptyRows && fillEmptyNum > 0) {
+                    Map<Integer, Integer> addRow = fillRowMap.get(i) != null ? fillRowMap.get(i) : new HashMap<>();
+                    addRow.put(j, fillEmptyNum);
+                    fillRowMap.put(i, addRow);
+                }
+            }
+            rowDefinition.setRowNumber(rowDefinition.getRowNumber() + 1);
+            rows.add(rowDefinition);
+        }
+    }
+
+    private UniverSheet sheet(UniverSheet sheet, Report report, Map<String, Formula> formulaMap, ColumnList columnList, Map<String, Map<Integer, Map<Integer, String>>> cellNameMapAll) {
+        int rowSize = report.getRows().size();
+        int columnSize = report.getColumns().size();
+        if (BeanUtil.isNotEmpty(columnList) && columnList.isColumnState()) {
+            buildColumn(report, columnList);
+//            buildFenceReport(report, columnList);
+        }
+        sheet.setCellData(new HashMap<>());
+        sheet.setMergeData(new ArrayList<>());
+        sheet.setRowData(new HashMap<>());
+        sheet.setColumnData(new HashMap<>());
+        Map<Integer, UniverSheetRowData> rowData = new HashMap<>();
+        Map<Integer, UniverSheetColumnData> columnData = new HashMap<>();
+        UniverSheet result = JsonUtil.getJsonToBean(sheet, UniverSheet.class);
+        List<Row> rows = report.getRows();
+        List<Column> columns = report.getColumns();
+        Map<Row, Map<Column, Cell>> cellMap = report.getRowColCellMap();
+        Map<Integer, Map<Integer, UniverSheetCellData>> cellData = new HashMap<>();
+        Map<Integer, Map<Integer, Cell>> formulaCellMap = new HashMap<>();
+        List<UniverSheetRange> mergeData = new ArrayList<>();
+        //获取冻结位置
+        UniverSheetFreeze sheetFreeze = sheet.getFreeze() != null ? sheet.getFreeze() : new UniverSheetFreeze();
+        int freezeRow = sheetFreeze.getStartRow();
+        List<Integer> freezeRowList = new ArrayList<>();
+        freezeRowList.add(freezeRow);
+        int freezeColumn = sheetFreeze.getStartColumn();
+        List<Integer> freezeColumnList = new ArrayList<>();
+        freezeColumnList.add(freezeColumn);
+        //绘制格子
+        for (int i = 0; i < rows.size(); i++) {
+            Row row = rows.get(i);
+            rowData.put(i, row.getSheetRowData());
+            if (row.getFreeze()) {
+                freezeRowList.add(i + 1);
+            }
+            for (int j = 0; j < columns.size(); j++) {
+                Column col = columns.get(j);
+                Cell cell = null;
+                if (cellMap.containsKey(row)) {
+                    Map<Column, Cell> colMap = cellMap.get(row);
+                    if (colMap.containsKey(col)) {
+                        cell = colMap.get(col);
+                    }
+                }
+                if (cell == null) {
+                    continue;
+                }
+                if (col.getFreeze()) {
+                    freezeColumnList.add(j + 1);
+                }
+                cell.setReference(new CellReference(i, j));
+                UniverSheetCellData sheetCellData = JsonUtil.getJsonToBean(cell.getCellData(), UniverSheetCellData.class);
+                if (BeanUtil.isEmpty(sheetCellData)) {
+                    sheetCellData = new UniverSheetCellData();
+                }
+
+                //获取函数格子
+                String cellName = cell.getName();
+                if (formulaMap.get(cellName) != null) {
+                    Map<Integer, Cell> data = formulaCellMap.get(i) != null ? formulaCellMap.get(i) : new HashMap<>();
+                    data.put(j, cell);
+                    formulaCellMap.put(i, data);
+                }
+
+                //合并格子
+                int startRow = i;
+                int endRow = i + (cell.getRowSpan() > 0 ? cell.getRowSpan() - 1 : cell.getRowSpan());
+                int startCol = j;
+                int endCol = j + (cell.getColSpan() > 0 ? cell.getColSpan() - 1 : cell.getColSpan());
+                int rowSpan = cell.getRowSpan();
+                int colSpan = cell.getColSpan();
+                StyleModel styleModel = cell.getStyleModel();
+                if (colSpan > 0 || rowSpan > 0) {
+                    //左、右边框
+                    boolean isL = ObjectUtil.isNotEmpty(styleModel.getL());
+                    boolean isR = ObjectUtil.isNotEmpty(styleModel.getR());
+                    //当合并数据大于数据限制
+//                    if (BeanUtil.isNotEmpty(columnList) && columnList.isColumnState()
+//                            && columnList.getColumnStyle().equals("col")
+//                            && endRow > columnList.getRowMaxNum()
+//                            && startRow<= columnList.getRowMaxNum()
+//                            && startRow>=columnList.getRowMinNum()) {
+//                        //首先计算总共合并的选项
+//                        int totalNum = endRow - startRow + 1;
+//                        //当前行的合并数量
+//                        int currentNum = columnList.getRowMaxNum() - startRow + 1;
+//                        //分栏中某一栏的数据数量
+//                        int fenceNum = columnList.getRowMaxNum() - columnList.getRowMinNum() + 1;
+//                        //先填充当前栏,计算剩下的数据
+//                        int remainNum = totalNum - currentNum;
+//
+//                        int resultNum = remainNum % fenceNum == 0 ? remainNum / fenceNum : remainNum / fenceNum + 1;
+//                        if (resultNum == 1) {
+//                            int needNum = 1;
+//                            makeRowRange(cellData, j, columnSize, needNum, sheetCellData, remainNum, mergeData, columnList);
+//                        } else {
+//                            for (int m = 0; m < resultNum; m++) {
+//
+//                                if (m == resultNum - 1) {
+//                                    int lastNum = remainNum % fenceNum;
+//                                    makeRowRange(cellData, j, columnSize, m + 1, sheetCellData, lastNum, mergeData, columnList);
+//                                } else {
+//                                    makeRowRange(cellData, j, columnSize, m + 1, sheetCellData, fenceNum, mergeData, columnList);
+//                                }
+//                            }
+//                        }
+//                        endRow = columnList.getRowMaxNum();
+//                    }
+                    for (int rowCount = startRow; rowCount <= endRow; rowCount++) {
+                        Map<Integer, UniverSheetCellData> dataMap = cellData.get(rowCount) != null ? cellData.get(rowCount) : new HashMap<>();
+                        UniverSheetCellData startData = dataMap.get(startCol) != null ? dataMap.get(startCol) : new UniverSheetCellData();
+                        startData.setS(isL ? styleModel.getL() : sheetCellData.getS());
+                        dataMap.put(startCol, startData);
+
+                        UniverSheetCellData endData = dataMap.get(endCol) != null ? dataMap.get(endCol) : new UniverSheetCellData();
+                        endData.setS(isR ? styleModel.getR() : sheetCellData.getS());
+                        dataMap.put(endCol, endData);
+
+                        cellData.put(rowCount, dataMap);
+                    }
+
+                    //上、下边框
+                    boolean isT = ObjectUtil.isNotEmpty(styleModel.getT());
+                    boolean isB = ObjectUtil.isNotEmpty(styleModel.getB());
+//                    if (BeanUtil.isNotEmpty(columnList) && columnList.isColumnState()
+//                            && columnList.getColumnStyle().equals("row") && endCol > columnList.getColMaxNum()
+//                            && startCol<= columnList.getColMaxNum()
+//                    &&startCol>=columnList.getColMinNum()) {
+//                        //首先计算总共合并的选项
+//                        int totalNum = endCol - startCol + 1;
+//                        //当前列的合并数量
+//                        int currentNum = columnList.getColMaxNum() - startCol + 1;
+//                        //分栏中某一栏的数据数量
+//                        int fenceNum = columnList.getColMaxNum() - columnList.getColMinNum() + 1;
+//                        //先填充当前栏,计算剩下的数据
+//                        int remainNum = totalNum - currentNum;
+//
+//                        int resultNum = remainNum % fenceNum == 0 ? remainNum / fenceNum : remainNum / fenceNum + 1;
+//                        if (resultNum == 1) {
+//                            makeColRange(cellData, sheetCellData, remainNum, mergeData, columnList, i + rowSize);
+//                        } else {
+//                            for (int m = 0; m < resultNum; m++) {
+//
+//                                if (m == resultNum - 1) {
+//                                    int lastNum = remainNum % fenceNum;
+//                                    makeColRange(cellData, sheetCellData, lastNum, mergeData, columnList, i + rowSize * (m + 1));
+//                                } else {
+//                                    makeColRange(cellData, sheetCellData, fenceNum, mergeData, columnList, i + rowSize * (m + 1));
+//                                }
+//                            }
+//                        }
+//                        endCol = columnList.getColMaxNum();
+//                    }
+                    for (int columnCount = startCol; columnCount <= endCol; columnCount++) {
+                        Map<Integer, UniverSheetCellData> startDataMap = cellData.get(startRow) != null ? cellData.get(startRow) : new HashMap<>();
+                        UniverSheetCellData startData = startDataMap.get(columnCount) != null ? startDataMap.get(columnCount) : new UniverSheetCellData();
+                        startData.setS(isT ? styleModel.getT() : sheetCellData.getS());
+                        startDataMap.put(columnCount, startData);
+                        cellData.put(startRow, startDataMap);
+
+                        Map<Integer, UniverSheetCellData> endDataMap = cellData.get(endRow) != null ? cellData.get(endRow) : new HashMap<>();
+                        UniverSheetCellData endData = endDataMap.get(columnCount) != null ? endDataMap.get(columnCount) : new UniverSheetCellData();
+                        endData.setS(isB ? styleModel.getB() : sheetCellData.getS());
+                        endDataMap.put(columnCount, endData);
+                        cellData.put(endRow, endDataMap);
+                    }
+                    //角样式
+                    boolean isLT = ObjectUtil.isNotEmpty(styleModel.getLt());
+                    boolean isRT = ObjectUtil.isNotEmpty(styleModel.getRt());
+                    Map<Integer, UniverSheetCellData> startDataMap = cellData.get(startRow) != null ? cellData.get(startRow) : new HashMap<>();
+                    UniverSheetCellData leftTopData = startDataMap.get(startCol) != null ? startDataMap.get(startCol) : new UniverSheetCellData();
+                    leftTopData.setS(isLT ? styleModel.getLt() : sheetCellData.getS());
+                    startDataMap.put(startCol, leftTopData);
+                    UniverSheetCellData rightTopData = startDataMap.get(endCol) != null ? startDataMap.get(endCol) : new UniverSheetCellData();
+                    rightTopData.setS(isRT ? styleModel.getRt() : sheetCellData.getS());
+                    startDataMap.put(endCol, rightTopData);
+                    cellData.put(startRow, startDataMap);
+
+                    boolean isLB = ObjectUtil.isNotEmpty(styleModel.getLb());
+                    boolean isRB = ObjectUtil.isNotEmpty(styleModel.getRb());
+                    Map<Integer, UniverSheetCellData> endDataMap = cellData.get(endRow) != null ? cellData.get(endRow) : new HashMap<>();
+                    UniverSheetCellData leftBottomData = endDataMap.get(startCol) != null ? endDataMap.get(startCol) : new UniverSheetCellData();
+                    leftBottomData.setS(isLB ? styleModel.getLb() : sheetCellData.getS());
+                    endDataMap.put(startCol, leftBottomData);
+                    UniverSheetCellData rightBottomData = endDataMap.get(endCol) != null ? endDataMap.get(endCol) : new UniverSheetCellData();
+                    rightBottomData.setS(isRB ? styleModel.getRb() : sheetCellData.getS());
+                    endDataMap.put(endCol, rightBottomData);
+                    cellData.put(endRow, endDataMap);
+
+                    Object sheetData = cell.getData();
+                    String type = cell.getType();
+                    boolean notRange = mergeData.stream().anyMatch(t -> t.getStartRow() <= startRow && t.getStartColumn() <= startCol && t.getEndRow() >= startRow && t.getEndColumn() >= startCol);
+                    //如果是图表,sheetData值又是null,不合并
+                    boolean notCellChart = CellDataEnum.cellChart.name().equals(type) && sheetData == null;
+                    if (!notRange && !notCellChart) {
+                        UniverSheetRange range = new UniverSheetRange();
+                        range.setStartRow(startRow);
+                        range.setEndRow(endRow);
+                        range.setStartColumn(startCol);
+                        range.setEndColumn(endCol);
+                        mergeData.add(range);
+                    }
+
+                }
+
+                //每个格子坐标
+                Map<Integer, Map<Integer, String>> cellNameMap = cellNameMapAll.get(cellName) != null ? cellNameMapAll.get(cellName) : new HashMap<>();
+                for (int rowNum = startRow; rowNum <= endRow; rowNum++) {
+                    Map<Integer, String> rowMap = cellNameMap.get(rowNum) != null ? cellNameMap.get(rowNum) : new HashMap<>();
+                    for (int colNum = startCol; colNum <= endCol; colNum++) {
+                        rowMap.put(colNum, cell.getReference().formatAsString());
+                    }
+                    cellNameMap.put(rowNum, rowMap);
+                }
+                cellNameMapAll.put(cellName, cellNameMap);
+
+                //赋值
+                Object sheetData = cell.getData();
+                int dataType = CellDataTypeEnum.String.getCode();
+                try {
+                    String value = String.valueOf(sheetData);
+                    new BigDecimal(value);
+                    if (value.length() < 16) {
+                        dataType = CellDataTypeEnum.Number.getCode();
+                    }
+                } catch (Exception ignored) {
+                }
+                if (sheetData instanceof Boolean) {
+                    dataType = CellDataTypeEnum.Boolean.getCode();
+                }
+                if (ObjectUtil.isNotEmpty(sheetCellData.getF())) {
+                    dataType = CellDataTypeEnum.Formula.getCode();
+                }
+                sheetCellData.setT(dataType);
+                sheetCellData.setV(sheetData);
+                sheetCellData.setP(sheetData == null ? null : sheetCellData.getP());
+                //判断超链接
+                if (ObjectUtil.isNotEmpty(sheetCellData.getP())&&!("text").equals(cell.getType())) {
+                    Object p = sheetCellData.getP();
+                    UniverProperties jsonToBean = JsonUtil.getJsonToBean(p, UniverProperties.class);
+                    if (BeanUtil.isNotEmpty(jsonToBean) && CollectionUtil.isEmpty(jsonToBean.getDrawings())) {
+                        UniverBody body = jsonToBean.getBody();
+                        if (BeanUtil.isNotEmpty(body)) {
+                            body.setDataStream(ObjectUtil.isNotEmpty(sheetData) ? sheetData.toString() + "\r\n" : "\r\n");
+                            //需要将数据进行修改
+                            if (ObjectUtil.isNotEmpty(sheetData)) {
+                                String string = sheetData.toString();
+                                List<UniverBodyConfig> sectionBreaks = body.getSectionBreaks();
+                                if (CollectionUtil.isNotEmpty(sectionBreaks)) {
+                                    sectionBreaks.get(0).setStartIndex(string.length() + 1);
+                                }
+                                List<UniverBodyConfig> textRuns = body.getTextRuns();
+                                if (CollectionUtil.isNotEmpty(textRuns)) {
+                                    textRuns.get(0).setEd(string.length());
+                                }
+                                List<UniverBodyConfig> paragraphs = body.getParagraphs();
+                                if (CollectionUtil.isNotEmpty(paragraphs)) {
+                                    paragraphs.get(0).setStartIndex(string.length() + 1);
+                                }
+                                List<UniverBodyConfig> customRanges = body.getCustomRanges();
+                                if (CollectionUtil.isNotEmpty(customRanges)) {
+                                    customRanges.get(0).setEndIndex(string.length() - 1);
+                                }
+                            }
+                            sheetCellData.setP(JSONObject.toJSON(jsonToBean));
+                        }
+                    }
+                }
+                UniverZxingModel zxing = cell.getZxing();
+                if (zxing != null) {
+                    UniverZxingModel zxingModel = JsonUtil.getJsonToBean(zxing, UniverZxingModel.class);
+                    zxingModel.setText(sheetData + "");
+                    UniverProperties properties = ImageUtil.zxing(zxingModel);
+                    sheetCellData.setP(properties);
+                    sheetCellData.setV("");
+                }
+
+                columnData.put(j, col.getSheetColumnData());
+                Map<Integer, UniverSheetCellData> cellDataMap = cellData.get(i) != null ? cellData.get(i) : new HashMap<>();
+                if (!cellDataMap.containsKey(j) || null == cellDataMap.get(j).getV()) {
+                    cellDataMap.put(j, sheetCellData);
+                }
+                cellData.put(i, cellDataMap);
+            }
+        }
+
+
+        //修改函数
+        List<Integer> rowList = new ArrayList<>(formulaCellMap.keySet()).stream().sorted(Comparator.naturalOrder()).collect(Collectors.toList());
+        for (Integer row : rowList) {
+            Map<Integer, Cell> rowMap = formulaCellMap.get(row) != null ? formulaCellMap.get(row) : new HashMap<>();
+            List<Integer> colList = new ArrayList<>(rowMap.keySet()).stream().sorted(Comparator.naturalOrder()).collect(Collectors.toList());
+            for (Integer col : colList) {
+                Cell cell = rowMap.get(col);
+                Formula formula = formulaMap.get(cell.getName());
+                if (formula != null) {
+                    if (formula.getCellName().isEmpty()) {
+                        List<String> functionName = formula.getCellNameList();
+                        Map<String, Map<Integer, Map<Integer, String>>> cellName = new HashMap<>();
+                        for (String name : functionName) {
+                            Map<Integer, Map<Integer, String>> functionCellMap = cellNameMapAll.get(name) != null ? cellNameMapAll.get(name) : new HashMap<>();
+                            Map<Integer, Map<Integer, String>> cellDataMap = new HashMap<>();
+                            for (Integer rowNum : functionCellMap.keySet()) {
+                                Map<Integer, String> colMap = new HashMap<>(functionCellMap.get(rowNum));
+                                cellDataMap.put(rowNum, colMap);
+                            }
+                            cellName.put(name, cellDataMap);
+                        }
+                        formula.setCellName(cellName);
+                    }
+                    formula.setRowNumber(row);
+                    formula.setColNumber(col);
+                    formulaList(cell, formula, report);
+                    //赋值
+                    UniverSheetCellData data = JsonUtil.getJsonToBean(cell.getCellData(), UniverSheetCellData.class);
+                    data.setT(CellDataTypeEnum.Formula.getCode());
+                    Map<Integer, UniverSheetCellData> cellDataMap = cellData.get(row) != null ? cellData.get(row) : new HashMap<>();
+                    cellDataMap.put(col, data);
+                    cellData.put(row, cellDataMap);
+                }
+            }
+        }
+        //赋值数据
+        result.setCellData(cellData);
+        result.setMergeData(mergeData);
+        result.setRowData(rowData);
+        result.setColumnData(columnData);
+        List<Integer> rowMax = new ArrayList<>();
+        rowMax.add(sheet.getRowCount());
+        rowMax.add(Collections.max(new ArrayList<>(rowData.keySet())) + 1);
+        result.setRowCount(Collections.max(rowMax));
+        List<Integer> columnMax = new ArrayList<>();
+        columnMax.add(sheet.getColumnCount());
+        columnMax.add(Collections.max(new ArrayList<>(columnData.keySet())) + 1);
+        result.setColumnCount(Collections.max(columnMax));
+
+        //赋值冻结数据
+        UniverSheetFreeze freeze = new UniverSheetFreeze();
+        freeze.setStartRow(Collections.max(freezeRowList));
+        freeze.setStartColumn(Collections.max(freezeColumnList));
+        freeze.setYSplit(freeze.getStartRow() > -1 ? freeze.getStartRow() : 0);
+        freeze.setXSplit(freeze.getStartColumn() > -1 ? freeze.getStartColumn() : 0);
+        result.setFreeze(freeze);
+        return result;
+    }
+
+    private void makeColRange(Map<Integer, Map<Integer, UniverSheetCellData>> cellData
+            , UniverSheetCellData sheetCellData, int remainNum, List<UniverSheetRange> mergeData
+            , ColumnList columnList, int i) {
+        int startNum = 0;
+        int endNum = 0;
+        int num = 0;
+
+
+        Map<Integer, UniverSheetCellData> integerUniverSheetCellDataMap = new HashMap<>();
+        int integer = 0;
+        while (num < remainNum) {
+
+            if (integer < columnList.getColMinNum() || integer > columnList.getColMaxNum()) {
+                integer++;
+                continue;
+            }
+            if (num == 0) {
+                startNum = integer;
+                integerUniverSheetCellDataMap.put(integer, sheetCellData);
+            } else {
+                UniverSheetCellData univerSheetCellData = new UniverSheetCellData();
+                integerUniverSheetCellDataMap.put(integer, univerSheetCellData);
+            }
+            integer++;
+            num++;
+            if (num >= remainNum) {
+                endNum = integer - 1;
+            }
+        }
+        cellData.put(i, integerUniverSheetCellDataMap);
+
+        UniverSheetRange univerSheetRange = new UniverSheetRange();
+        univerSheetRange.setStartRow(i);
+        univerSheetRange.setEndRow(i);
+        univerSheetRange.setStartColumn(startNum);
+        univerSheetRange.setEndColumn(endNum);
+        mergeData.add(univerSheetRange);
+    }
+
+    /**
+     * 分栏分组的情况下,创建合并数据
+     *
+     * @param cellData
+     * @param j
+     * @param columnSize
+     * @param needNum
+     * @param sheetCellData
+     * @param max
+     * @param mergeData
+     */
+    private static void makeRowRange(Map<Integer, Map<Integer, UniverSheetCellData>> cellData, int j, int columnSize, int needNum, UniverSheetCellData sheetCellData,
+                                     int max, List<UniverSheetRange> mergeData, ColumnList columnList) {
+        int startNum = 0;
+        int endNum = 0;
+        int num = 0;
+
+        for (Integer integer = columnList.getRowMinNum(); integer <= columnList.getRowMaxNum(); integer++) {
+
+            Map<Integer, UniverSheetCellData> integerUniverSheetCellDataMap = cellData.get(integer);
+            if (CollectionUtil.isEmpty(integerUniverSheetCellDataMap)) {
+                integerUniverSheetCellDataMap = new HashMap<>();
+                cellData.put(integer, integerUniverSheetCellDataMap);
+            }
+            if (num == 0) {
+                startNum = integer;
+                integerUniverSheetCellDataMap.put(j + columnSize * needNum, sheetCellData);
+            } else {
+                UniverSheetCellData univerSheetCellData = new UniverSheetCellData();
+                integerUniverSheetCellDataMap.put(j + columnSize * needNum, univerSheetCellData);
+            }
+            num++;
+            if (num >= max) {
+                endNum = integer;
+                break;
+            }
+        }
+        UniverSheetRange univerSheetRange = new UniverSheetRange();
+        univerSheetRange.setStartRow(startNum);
+        univerSheetRange.setEndRow(endNum);
+        univerSheetRange.setStartColumn(j + columnSize * needNum);
+        univerSheetRange.setEndColumn(j + columnSize * needNum);
+        mergeData.add(univerSheetRange);
+    }
+
+
+    private void buildColumn(Report report, ColumnList columnModel) {
+        if (columnModel == null) {
+            return;
+        }
+        if (!columnModel.isColumnState()) {
+            return;
+        }
+        Map<String, List<Cell>> cellsMap = report.getCellsMap();
+        Map<Row, Map<Column, Cell>> rowColCellMap = report.getRowColCellMap();
+        List<Column> columns = report.getColumns();
+        List<Row> rows = report.getRows();
+        String copyCol = columnModel.getCopyCol();
+        String copyRow = columnModel.getCopyRow();
+        Integer rowCount = columnModel.getRowCount();
+        Integer maxCol = columnModel.getMaxCol();
+        Integer colCount = columnModel.getColCount();
+        Integer maxRow = columnModel.getMaxRow();
+        boolean isCol = Objects.equals(ColumnEnum.col.getType(), columnModel.getColumnStyle());
+        boolean isType = Objects.equals(ColumnEnum.columnType.getType(), columnModel.getColumnType());
+        String copyNum = isCol ? copyCol : copyRow;
+        Map<Integer, Integer> copyMap = new HashMap<>();
+        if (StringUtil.isNotEmpty(copyNum)) {
+            String[] numOne = copyNum.split(",");
+            for (String string : numOne) {
+                String[] numTwo = string.split("-");
+                for (String s : numTwo) {
+                    try {
+                        Integer num = Integer.valueOf(s);
+                        copyMap.put(num, num);
+                    } catch (Exception e) {
+                        System.out.println("复制的格子有问题");
+                        return;
+                    }
+                }
+            }
+        }
+
+        //分栏数据的处理
+        String columnData = columnModel.getColumnData();
+        CellRangeAddress cellAddresses;
+        try {
+            cellAddresses = CellRangeAddress.valueOf(columnData);
+        } catch (Exception e) {
+            System.out.println("分栏的格子有问题");
+            return;
+        }
+
+
+        //获取分栏的数据格子
+        Map<String, String> cellName = new HashMap<>();
+        //处理数据分成多少栏
+        List<Integer> dataList = new ArrayList<>();
+        dataList.add(0);
+        int firstRow = cellAddresses.getFirstRow();
+        int lastRow = cellAddresses.getLastRow();
+        int firstColumn = cellAddresses.getFirstColumn();
+        int lastColumn = cellAddresses.getLastColumn();
+        int columnOffset = lastColumn - firstColumn;
+        int rowOffset = lastRow - firstRow;
+        for (int rowNum = firstRow; rowNum <= lastRow; rowNum++) {
+            for (int colNum = firstColumn; colNum <= lastColumn; colNum++) {
+                CellReference reference = new CellReference(rowNum, colNum);
+                String format = reference.formatAsString();
+                List<Cell> cells = cellsMap.get(format) != null ? cellsMap.get(format) : new ArrayList<>();
+                dataList.add(cells.size());
+                cellName.put(format, format);
+            }
+        }
+
+        //规定
+        List<Column> beforeColList = new ArrayList<>();
+        List<Column> afterColList = new ArrayList<>();
+        List<Row> beforeRowList = new ArrayList<>();
+        List<Row> afterRowList = new ArrayList<>();
+
+        //最大数量
+        int dataSize = Collections.max(dataList);
+        //最大值
+        int fenceNum = isCol ? maxCol : maxRow;
+        if (isCol) {
+            List<Column> beforeList = columns.subList(0, lastColumn + 1);
+            beforeColList = new ArrayList<>(beforeList);
+            List<Column> afterList = columns
+                    .subList(Math.min((lastColumn + 1), (columns.size() - 1)), columns.size() - 1);
+            afterColList = new ArrayList<>(afterList);
+            beforeRowList = rows;
+        } else {
+            List<Row> beforeList = rows.subList(0, lastRow + 1);
+            beforeRowList = new ArrayList<>(beforeList);
+            List<Row> afterList = rows
+                    .subList(Math.min((lastRow + 1), (rows.size() - 1)), rows.size() - 1);
+            afterRowList = new ArrayList<>(afterList);
+            beforeColList = columns;
+        }
+        if (isType) {
+            if (isCol) {
+                if (rowCount < 1) {
+                    return;
+                }
+                fenceNum = (dataSize / rowCount) + (dataSize % rowCount == 0 ? 0 : 1);
+            } else {
+                if (colCount < 1) {
+                    return;
+                }
+                fenceNum = (dataSize / colCount) + (dataSize % colCount == 0 ? 0 : 1);
+            }
+        }
+        if (fenceNum < 1 || dataSize < fenceNum) {
+            return;
+        }
+        //移动几行
+        int fenceCount = (dataSize / fenceNum) + (dataSize % fenceNum == 0 ? 0 : 1);
+        //格子的第一个位置
+        Map<String, Map<String, Integer>> cellFirst = new HashMap<>();
+        //格子的数量
+        Map<String, Integer> count = new HashMap<>();
+
+        //添加的格子
+        Map<Integer, Column> addColumnList = new HashMap<>();
+        Map<Integer, Row> addRowList = new HashMap<>();
+        Map<Row, Map<Column, Cell>> rowColMap = new HashMap<>();
+        //删除的格子
+        Map<Row, Map<Column, Cell>> delColList = new HashMap<>();
+        //添加第几行
+        Map<String, Integer> numMap = new HashMap<>();
+        Map<String, Integer> cellNum = new HashMap<>();
+
+        for (int i = 0; i < rows.size(); i++) {
+            Row row = rows.get(i);
+            for (int j = 0; j < columns.size(); j++) {
+                Column col = columns.get(j);
+                Cell cell = null;
+                if (rowColCellMap.containsKey(row)) {
+                    Map<Column, Cell> colMap = rowColCellMap.get(row);
+                    if (colMap.containsKey(col)) {
+                        cell = colMap.get(col);
+                    }
+                }
+                if (cell == null) {
+                    continue;
+                }
+                String name = cell.getName();
+                Map<String, Integer> map = new HashMap<>();
+                map.put(ColumnEnum.row.getType(), i);
+                map.put(ColumnEnum.col.getType(), j);
+                Map<String, Integer> firstMap = cellFirst.get(name) != null ? cellFirst.get(name) : map;
+                cellFirst.put(name, firstMap);
+
+                Value value = cell.getValue();
+                //分栏数据
+                if (cellName.get(name) != null) {
+//                    if (!(value instanceof DatasetValue)) {
+//                        continue;
+//                    }
+                    List<Integer> spanList = new ArrayList<>();
+                    int countNum = count.get(name) != null ? count.get(name) : 0;
+                    int num = numMap.get(name) != null ? numMap.get(name) : 0;
+                    int addCount = cellNum.get(name) != null ? cellNum.get(name) : 0;
+                    if (isCol) {
+                        if (columns.indexOf(col) > lastColumn || columns.indexOf(col) < firstColumn) {
+                            continue;
+                        }
+                        int rowSpan = cell.getRowSpan();
+                        int total = rowSpan > 0 ? rowSpan : 1;
+
+                        //重新计算合并格子
+                        Map<Integer, Integer> addMap = new HashMap<>();
+                        Map<Integer, Integer> spanMap = new HashMap<>();
+                        span(total, num, fenceNum, addMap, spanMap, rowSpan);
+
+                        //分栏数据调整
+                        for (int k = 0; k < total; k++) {
+                            spanList.add(addCount);
+                            if (addMap.get(k) != null) {
+                                int span = spanMap.get(k) != null ? spanMap.get(k) : rowSpan;
+                                if (addCount > 0) {
+                                    //获取数据
+                                    int addRow = firstMap.get(ColumnEnum.row.getType()) + num;
+                                    Row cellRow = rows.size() > addRow && rows.get(addRow) != null ? rows.get(addRow) : new Row(new ArrayList<>());
+                                    Map<Column, Cell> addColumnMap = rowColMap.get(cellRow) != null ? rowColMap.get(cellRow) : new HashMap<>();
+                                    int addColumn = firstMap.get(ColumnEnum.col.getType()) + ((columnOffset + 1) * addCount) + OFFSET * addCount;
+                                    //添加数据
+                                    Cell newCell = cell.newCell();
+                                    newCell.setData(cell.getData());
+                                    newCell.setRowSpan(span);
+                                    Column columnsModel = addColumnList.get(addColumn) != null ? addColumnList.get(addColumn) : new Column(new ArrayList<>());
+                                    if (null == addColumnList.get(addColumn)) {
+                                        columnsModel.setSheetColumnData(col.getSheetColumnData());
+                                    }
+                                    columnsModel.getCells().add(newCell);
+                                    addColumnList.put(addColumn, columnsModel);
+                                    addColumnMap.put(columnsModel, newCell);
+                                    rowColMap.put(cellRow, addColumnMap);
+                                } else {
+                                    cell.setRowSpan(span);
+                                }
+                            }
+                            num += 1;
+                            if (num >= fenceNum) {
+                                addCount += 1;
+                                num = 0;
+                            }
+                        }
+
+                    } else {
+                        if (rows.indexOf(row) > lastRow || rows.indexOf(row) < firstRow) {
+                            continue;
+                        }
+                        int colSpan = cell.getColSpan();
+                        int total = colSpan > 0 ? colSpan : 1;
+
+                        //重新计算合并格子
+                        Map<Integer, Integer> addMap = new HashMap<>();
+                        Map<Integer, Integer> spanMap = new HashMap<>();
+                        span(total, num, fenceNum, addMap, spanMap, colSpan);
+
+                        //分栏数据调整
+                        for (int k = 0; k < total; k++) {
+                            spanList.add(addCount);
+                            if (addMap.get(k) != null) {
+                                int span = spanMap.get(k) != null ? spanMap.get(k) : colSpan;
+                                if (addCount > 0) {
+                                    //获取数据
+                                    int addRow = firstMap.get(ColumnEnum.row.getType()) + ((rowOffset + 1) * addCount) + OFFSET * addCount;
+                                    Row cellRow = addRowList.get(addRow) != null ? addRowList.get(addRow) : new Row(new ArrayList<>());
+                                    if (null == addRowList.get(addRow)) {
+                                        cellRow.setSheetRowData(row.getSheetRowData());
+                                    }
+                                    int addColumn = firstMap.get(ColumnEnum.col.getType()) + num;
+                                    Map<Column, Cell> addColumnMap = rowColMap.get(cellRow) != null ? rowColMap.get(cellRow) : new HashMap<>();
+                                    //添加数据
+                                    Cell newCell = cell.newCell();
+                                    newCell.setData(cell.getData());
+                                    newCell.setColSpan(span);
+                                    Column column = columns.size() > addColumn ? columns.get(addColumn) : new Column(new ArrayList<>());
+                                    if (null == columns.get(addColumn)) {
+                                        column.setSheetColumnData(col.getSheetColumnData());
+                                    }
+                                    Map<Column, Cell> columnMap = new HashMap<>();
+                                    columnMap.put(column, newCell);
+                                    addColumnMap.putAll(columnMap);
+                                    addRowList.put(addRow, cellRow);
+                                    rowColMap.put(cellRow, addColumnMap);
+                                } else {
+                                    cell.setColSpan(span);
+                                }
+                            }
+                            num += 1;
+                            if (num >= fenceNum) {
+                                addCount += 1;
+                                num = 0;
+                            }
+                        }
+
+                    }
+                    countNum += 1;
+                    cellNum.put(name, addCount);
+                    numMap.put(name, num);
+                    count.put(name, countNum);
+
+                    //删除超过的数据
+                    if (!spanList.isEmpty()) {
+                        int minAddCount = Collections.min(spanList);
+                        if (minAddCount > 0) {
+                            //删除数据
+                            Map<Column, Cell> delete = delColList.get(row) != null ? delColList.get(row) : new HashMap<>();
+                            delete.put(col, cell);
+                            delColList.put(row, delete);
+                        }
+                    }
+
+                    //补充空白行
+                    if (columnModel.isFillEmptyRows()) {
+                        //最后一行
+                        List<Cell> cells = cellsMap.get(name) != null ? cellsMap.get(name) : new ArrayList<>();
+                        if (cells.size() == countNum) {
+                            int fillNum = numMap.get(name) != null ? numMap.get(name) : 0;
+                            if (fillNum > 0) {
+                                if (isCol) {
+                                    for (int k = fillNum; k < fenceNum; k++) {
+                                        //获取数据
+                                        int addColumn = firstMap.get(ColumnEnum.col.getType()) + ((columnOffset + 1) * addCount) + OFFSET * addCount;
+                                        int addRow = firstMap.get(ColumnEnum.row.getType()) + k;
+                                        Row cellRow = rows.size() > addRow && rows.get(addRow) != null ? rows.get(addRow) : new Row(new ArrayList<>());
+                                        Map<Column, Cell> addColumnMap = rowColMap.get(cellRow) != null ? rowColMap.get(cellRow) : new HashMap<>();
+                                        //添加数据
+                                        Cell filleCcell = cell.newCell();
+                                        filleCcell.setColSpan(0);
+                                        filleCcell.setRowSpan(0);
+                                        filleCcell.setData(null);
+                                        Column columnsModel = addColumnList.get(addColumn) != null ? addColumnList.get(addColumn) : new Column(new ArrayList<>());
+                                        columnsModel.getCells().add(filleCcell);
+                                        addColumnList.put(addColumn, columnsModel);
+                                        addColumnMap.put(columnsModel, filleCcell);
+                                        rowColMap.put(cellRow, addColumnMap);
+                                    }
+                                } else {
+                                    for (int k = fillNum; k < fenceNum; k++) {
+                                        //获取数据
+                                        int addColumn = firstMap.get(ColumnEnum.col.getType()) + k;
+                                        int addRow = firstMap.get(ColumnEnum.row.getType()) + ((rowOffset + 1) * addCount) + OFFSET * addCount;
+                                        Row cellRow = addRowList.get(addRow) != null ? addRowList.get(addRow) : new Row(new ArrayList<>());
+                                        Map<Column, Cell> addColumnMap = rowColMap.get(cellRow) != null ? rowColMap.get(cellRow) : new HashMap<>();
+                                        Cell filleCcell = cell.newCell();
+                                        filleCcell.setColSpan(0);
+                                        filleCcell.setRowSpan(0);
+                                        filleCcell.setData(null);
+                                        //添加数据
+                                        Column column = columns.size() > addColumn ? columns.get(addColumn) : new Column(new ArrayList<>());
+                                        Map<Column, Cell> columnMap = new HashMap<>();
+                                        columnMap.put(column, filleCcell);
+                                        addColumnMap.putAll(columnMap);
+                                        addRowList.put(addRow, cellRow);
+                                        rowColMap.put(cellRow, addColumnMap);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+
+                //复制数据
+                if (!copyMap.isEmpty()) {
+                    if (value instanceof SimpleValue) {
+                        CellReference reference = new CellReference(name);
+                        int referenceCol = reference.getCol() + 1;
+                        int referenceRow = reference.getRow() + 1;
+                        if (isCol) {
+                            if (columns.indexOf(col) > lastColumn || columns.indexOf(col) < firstColumn) {
+                                continue;
+                            }
+                            if (copyMap.get(referenceRow) != null) {
+                                for (int k = 1; k < fenceCount; k++) {
+                                    //获取数据
+                                    Map<Column, Cell> addColumnMap = rowColMap.get(row) != null ? rowColMap.get(row) : new HashMap<>();
+                                    int addColumn = j + ((columnOffset + 1) * k) + OFFSET * k;
+                                    //添加数据
+                                    Column columnsModel = addColumnList.get(addColumn) != null ? addColumnList.get(addColumn) : new Column(new ArrayList<>());
+                                    if (null == addColumnList.get(addColumn)) {
+                                        columnsModel.setSheetColumnData(col.getSheetColumnData());
+                                    }
+                                    columnsModel.getCells().add(cell);
+                                    addColumnList.put(addColumn, columnsModel);
+                                    addColumnMap.put(columnsModel, cell);
+                                    rowColMap.put(row, addColumnMap);
+                                }
+                            }
+                        } else {
+                            if (rows.indexOf(row) > lastRow || rows.indexOf(row) < firstRow) {
+                                continue;
+                            }
+                            if (copyMap.get(referenceCol) != null) {
+                                for (int k = 1; k < fenceCount; k++) {
+                                    //获取数据
+                                    int addRow = i + ((rowOffset + 1) * k) + OFFSET * k;
+                                    Row rowModel = addRowList.get(addRow) != null ? addRowList.get(addRow) : new Row(new ArrayList<>());
+                                    if (null == addRowList.get(addRow)) {
+                                        rowModel.setSheetRowData(row.getSheetRowData());
+                                    }
+                                    Map<Column, Cell> addColumnMap = rowColMap.get(rowModel) != null ? rowColMap.get(rowModel) : new HashMap<>();
+                                    //添加数据
+                                    Column column = columns.size() > j ? columns.get(j) : new Column(new ArrayList<>());
+                                    Map<Column, Cell> columnMap = new HashMap<>();
+                                    columnMap.put(column, cell);
+                                    addRowList.put(addRow, rowModel);
+                                    addColumnMap.putAll(columnMap);
+                                    rowColMap.put(rowModel, addColumnMap);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        List<Column> delColumns = new ArrayList<>();
+        //删除没有用的格子
+        for (Row row : delColList.keySet()) {
+            Map<Column, Cell> columnMap = rowColCellMap.get(row);
+            if (columnMap == null) {
+                continue;
+            }
+            Map<Column, Cell> delColumnMap = delColList.get(row) != null ? delColList.get(row) : new HashMap<>();
+            for (Column column : delColumnMap.keySet()) {
+                columnMap.remove(column);
+            }
+            //特殊处理列
+
+            //删除列的数据
+            List<Column> deleteColumnList = columns.stream().filter(e -> new ArrayList<>(delColumnMap.keySet()).contains(e)).collect(Collectors.toList());
+            for (Column column : deleteColumnList) {
+                Cell delCell = delColumnMap.get(column);
+                List<Cell> cells = column.getCells();
+                cells.remove(delCell);
+                if (!isCol
+                        && cellName.get(delCell.getName()) != null
+                        && delCell.getType().equals("text")) {
+                    delColumns.add(column);
+                }
+                if (cells.isEmpty()) {
+                    columns.remove(column);
+                }
+            }
+
+            //删除行的数据
+
+
+            if (columnMap.isEmpty()) {
+                rows.remove(row);
+            } else {
+                List<Cell> cells = new ArrayList<>(columnMap.values());
+                boolean b = cells.stream().allMatch(cell ->
+                        cell.getType() == null || !cell.getType().equals("text") ||
+                                StringUtil.isEmpty(ObjectUtil
+                                        .defaultIfNull(cell.getData(), "")
+                                        .toString()));
+                if (b) {
+                    rows.remove(row);
+                }
+            }
+        }
+
+        if (CollectionUtil.isNotEmpty(delColumns)) {
+            for (Column delColumn : delColumns) {
+                List<Cell> cells = delColumn.getCells();
+                boolean b = cells.stream().allMatch(cell ->
+                        (cell.getType() == null || cell.getType().equals("text")) &&
+                                StringUtil.isEmpty(ObjectUtil
+                                        .defaultIfNull(cell.getData(), "")
+                                        .toString()));
+                if (b) {
+                    columns.remove(delColumn);
+                }
+            }
+        }
+
+
+        //新增行数据
+        List<Integer> columList = new ArrayList<>(addColumnList.keySet()).stream().sorted(Comparator.naturalOrder()).collect(Collectors.toList());
+        int addColumnCount = columList.isEmpty() ? 0 : Collections.max(columList);
+        for (int i = beforeColList.size(); i < addColumnCount; i++) {
+            columns.add(new Column(new ArrayList<>()));
+        }
+        for (Integer col : columList) {
+            Column addColumn = addColumnList.get(col);
+            if (addColumn == null) {
+                continue;
+            }
+            beforeColList.add(col, addColumn);
+        }
+
+        //新增列数据
+        List<Integer> rowList = new ArrayList<>(addRowList.keySet()).stream().sorted(Comparator.naturalOrder()).collect(Collectors.toList());
+        int addRowCount = rowList.isEmpty() ? 0 : Collections.max(rowList);
+        for (int i = beforeRowList.size(); i < addRowCount; i++) {
+            rows.add(new Row(new ArrayList<>()));
+        }
+        for (Integer row : rowList) {
+            Row addRow = addRowList.get(row);
+            if (addRow == null) {
+                continue;
+            }
+            beforeRowList.add(row, addRow);
+        }
+        beforeRowList.addAll(afterRowList);
+        beforeColList.addAll(afterColList);
+        report.setRows(beforeRowList);
+        report.setColumns(beforeColList);
+
+        //行列对应的数据
+        for (Row row : rowColMap.keySet()) {
+            Map<Column, Cell> cellMap = rowColMap.get(row) != null ? rowColMap.get(row) : new HashMap<>();
+            Map<Column, Cell> columnMap = rowColCellMap.get(row) != null ? rowColCellMap.get(row) : new HashMap<>();
+            columnMap.putAll(cellMap);
+            rowColCellMap.put(row, columnMap);
+        }
+    }
+
+
+    private void span(int total, int num, int fenceNum, Map<Integer, Integer> addMap, Map<Integer, Integer> spanMap, int span) {
+        addMap.put(0, 0);
+        int firstData = fenceNum - num;
+        spanMap.put(0, Collections.min(ImmutableList.of(span, firstData)));
+        if (total > 1) {
+            if (firstData <= total) {
+                int dataSize = total - firstData;
+                int size = (dataSize / fenceNum) + (dataSize % fenceNum == 0 ? 0 : 1);
+                for (int j = 0; j < size; j++) {
+                    int index = firstData + (j * fenceNum);
+                    addMap.put(index, index);
+                    if (j == size - 1) {
+                        spanMap.put(index, total - index);
+                    } else {
+                        spanMap.put(index, fenceNum);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * 分栏处理
+     *
+     * @param report
+     * @param columnList
+     */
+    private void buildFenceReport(Report report, ColumnList columnList) {
+        Map<String, List<Cell>> cellsMap = report.getCellsMap();
+        Map<Row, Map<Column, Cell>> rowColCellMap = report.getRowColCellMap();
+        List<Column> columns = report.getColumns();
+        List<Row> rows = report.getRows();
+        String copyCol = columnList.getCopyCol();
+        String copyRow = columnList.getCopyRow();
+        Integer rowCount = columnList.getRowCount();
+        Integer maxCol = columnList.getMaxCol();
+        Integer colCount = columnList.getColCount();
+        Integer maxRow = columnList.getMaxRow();
+        List<Integer> collect = getCopyCollect(columnList.getColumnStyle().equals("col") ? copyCol : copyRow);
+        //分栏数据的处理
+        String columnData = columnList.getColumnData();
+        CellRangeAddress cellAddresses = null;
+        try {
+            cellAddresses = CellRangeAddress.valueOf(columnData);
+        } catch (RuntimeException e) {
+            throw new RuntimeException(e);
+        }
+
+        //不参加分栏的数据(不包括复制数据)
+        List<String> strings = new ArrayList<>();
+        for (String string : cellsMap.keySet()) {
+            CellRangeAddress cellRangeAddress = CellRangeAddress.valueOf(string);
+            if ((cellRangeAddress.getFirstRow() < cellAddresses.getFirstRow()
+                    || cellRangeAddress.getFirstRow() > cellAddresses.getLastRow()
+                    || cellRangeAddress.getFirstColumn() < cellAddresses.getFirstColumn()
+                    || cellRangeAddress.getFirstColumn() > cellAddresses.getLastColumn())
+                    && ((columnList.getColumnStyle().equals("col") && !collect.contains(cellRangeAddress.getFirstRow()))
+                    || (columnList.getColumnStyle().equals("row") && !collect.contains(cellRangeAddress.getFirstColumn())))) {
+                strings.add(string);
+            }
+        }
+        //行分栏,分成n栏
+        if (BeanUtil.isNotEmpty(columnList) && columnList.isColumnState() && columnList.getColumnStyle().equals("col")) {
+            //未分栏数据集合
+            Map<Row, Map<Column, Cell>> rowMapHashMap = new HashMap<>();
+            //未分栏行集合
+            List<Row> rowNoNeed = new ArrayList<>(rows.size());
+            rowNoNeed.addAll(Collections.nCopies(rows.size(), null));
+            for (Row row : rowColCellMap.keySet()) {
+
+                Map<Column, Cell> columnCellMap = rowColCellMap.get(row);
+                Row addRow = new Row(new ArrayList<>());
+                int i = rows.indexOf(row);
+                HashMap<Column, Cell> columnCellHashMap = new HashMap<>();
+                Iterator<Column> iterator = columnCellMap.keySet().iterator();
+                while (iterator.hasNext()) {
+                    Column column = iterator.next();
+                    Cell cell = columnCellMap.get(column);
+                    //如果存在不分栏的数据
+                    if (strings.contains(cell.getName())) {
+                        columnCellHashMap.put(column, cell);
+                        if (collect.contains(i)) {
+                            continue;
+                        }
+                        iterator.remove();
+                    }
+
+
+                }
+                if (!columnCellHashMap.isEmpty()) {
+                    addRow.setSheetRowData(row.getSheetRowData());
+                    rowNoNeed.set(i, addRow);
+                    rowMapHashMap.put(addRow, columnCellHashMap);
+                }
+
+            }
+            //复制行
+            List<Row> copyRowList = collect.stream().map(item -> {
+                for (Row row : rows) {
+                    int i = parseRowNum(row);
+                    if (i == item) {
+                        return row;
+                    }
+                }
+                return null;
+            }).filter(Objects::nonNull).collect(Collectors.toList());
+            //删除数据
+            for (Row row : rowColCellMap.keySet()) {
+                if (copyRowList.contains(row)) {
+                    continue;
+                }
+                Map<Column, Cell> columnCellMap = rowColCellMap.get(row);
+                Iterator<Column> iterator = columnCellMap.keySet().iterator();
+                while (iterator.hasNext()) {
+                    Column column = iterator.next();
+                    Cell cell = columnCellMap.get(column);
+                    if (strings.contains(cell.getName())) {
+                        iterator.remove();
+                    }
+                }
+            }
+
+            int firstRow = cellAddresses.getFirstRow();
+            int lastRow = cellAddresses.getLastRow();
+            int dataSize = (int) rows.stream().filter(item -> {
+                int rowNum = parseRowNum(item);
+                return rowNum >= firstRow && rowNum <= lastRow;
+            }).count();
+            //分栏数目
+            int fenceNum = 0;
+            //分栏长度
+            int fenceDataSize = 0;
+            if (columnList.getColumnType().equals("2")) {
+                if (rowCount == 1) {
+                    return;
+                }
+                fenceDataSize = dataSize % rowCount == 0 ? dataSize / rowCount : dataSize / rowCount + 1;
+                fenceNum = rowCount;
+            } else {
+                if (maxCol < 1) {
+                    return;
+                }
+                fenceDataSize = maxCol;
+                fenceNum = dataSize % maxCol == 0 ? dataSize / maxCol : dataSize / maxCol + 1;
+            }
+            rowChoice(report, columnList, columns, fenceNum
+                    , rows, copyRowList, rowColCellMap
+                    , firstRow, lastRow, rowMapHashMap, rowNoNeed, fenceDataSize);
+        } else if (BeanUtil.isNotEmpty(columnList) && columnList.isColumnState() && columnList.getColumnStyle().equals("row")) {
+
+            //处理复制列
+            List<Column> copyColumnList = collect.stream().map(item -> {
+                for (Column column : columns) {
+                    int i = column.getColumnKey();
+                    if (i - 1 == item) {
+                        return column;
+                    }
+                }
+                return null;
+            }).filter(Objects::nonNull).collect(Collectors.toList());
+
+
+            int firstColumn = cellAddresses.getFirstColumn();
+            int lastColumn = cellAddresses.getLastColumn();
+            int dataSize = (int) columns.stream().filter(item -> {
+                int columnKey = item.getColumnKey();
+                return columnKey - 1 >= firstColumn && columnKey - 1 <= lastColumn;
+            }).count();
+            //分栏数目
+            int fenceNum = 0;
+            //分栏长度
+            int fenceDataSize = 0;
+            if (columnList.getColumnType().equals("2")) {
+                if (colCount == 1) {
+                    return;
+                }
+                fenceDataSize = dataSize % colCount == 0 ? dataSize / colCount : dataSize / colCount + 1;
+                fenceNum = colCount;
+            } else {
+                if (maxRow < 1) {
+                    return;
+                }
+                fenceDataSize = maxRow;
+                fenceNum = dataSize % maxRow == 0 ? dataSize / maxRow : dataSize / maxRow + 1;
+            }
+
+            //未分栏数据集合
+            Map<Row, Map<Column, Cell>> rowMapHashMap = new HashMap<>();
+            //未分栏行集合
+            List<Row> rowNoNeed = new ArrayList<>(rows.size());
+            List<Column> newColumnList = new ArrayList<>();
+            rowNoNeed.addAll(Collections.nCopies(rows.size(), null));
+            for (Row row : rowColCellMap.keySet()) {
+
+                Map<Column, Cell> columnCellMap = rowColCellMap.get(row);
+                Row addRow = new Row(new ArrayList<>());
+                int i = rows.indexOf(row);
+                HashMap<Column, Cell> columnCellHashMap = new HashMap<>();
+                Iterator<Column> iterator = columnCellMap.keySet().iterator();
+                while (iterator.hasNext()) {
+                    Column column = iterator.next();
+                    Cell cell = columnCellMap.get(column);
+                    int index = columns.indexOf(column);
+                    //如果存在不分栏的数据
+                    if (strings.contains(cell.getName())) {
+                        if (collect.contains(index)) {
+                            continue;
+                        }
+                        int tempColumnNumber = column.getTempColumnNumber();
+                        int columnKey = column.getColumnKey();
+                        int finalFenceDataSize = fenceDataSize;
+                        List<Column> collected = newColumnList.stream()
+                                .filter(t -> t.getTempColumnNumber()
+                                        == tempColumnNumber + copyColumnList.size() + finalFenceDataSize
+                                        && t.getColumnKey() == columnKey)
+                                .collect(Collectors.toList());
+                        if (collected.isEmpty()) {
+                            Column newColumn = new Column(new ArrayList<>());
+                            newColumn.setTempColumnNumber(tempColumnNumber + copyColumnList.size() + fenceDataSize);
+                            newColumn.setColumnKey(columnKey);
+                            newColumnList.add(newColumn);
+                            columnCellHashMap.put(newColumn, cell);
+                        } else {
+                            columnCellHashMap.put(collected.get(0), cell);
+                        }
+
+
+                        iterator.remove();
+                    }
+
+
+                }
+                if (!columnCellHashMap.isEmpty()) {
+                    addRow.setSheetRowData(row.getSheetRowData());
+                    rowNoNeed.set(i, addRow);
+                    rowMapHashMap.put(addRow, columnCellHashMap);
+                }
+
+            }
+            //删掉数据
+            for (Row row : rowColCellMap.keySet()) {
+                Map<Column, Cell> columnCellMap = rowColCellMap.get(row);
+                Iterator<Column> iterator = columnCellMap.keySet().iterator();
+                while (iterator.hasNext()) {
+                    Column column = iterator.next();
+                    Cell cell = columnCellMap.get(column);
+                    if (strings.contains(cell.getName()) && !copyColumnList.contains(column)) {
+                        iterator.remove();
+                    }
+                }
+            }
+
+            colChoice(report, columnList, rows, columns, firstColumn
+                    , lastColumn, fenceDataSize, rowColCellMap, copyColumnList, rowMapHashMap, rowNoNeed, fenceNum, newColumnList);
+        }
+
+
+    }
+
+    private static void colChoice(Report report, ColumnList columnList, List<Row> rows
+            , List<Column> columns, int firstColumn, int lastColumn
+            , int fenceDataSize, Map<Row, Map<Column, Cell>> rowColCellMap, List<Column> copyColumnList
+            , Map<Row, Map<Column, Cell>> rowMapHashMap, List<Row> rowNoNeed, int fenceNum, List<Column> newColumnList) {
+        //行数
+        int rowSize = rows.size();
+        //造行
+        List<Row> rowArrayList = new ArrayList<>();
+        for (int i = 0; i < (fenceNum - 1); i++) {
+            for (int j = 0; j < rowSize; j++) {
+                Row row = new Row(new ArrayList<>());
+                row.setTempRowNumber(rowSize * (i + 1) + j);
+                row.setSheetRowData(rows.get(j).getSheetRowData());
+                rowArrayList.add(row);
+            }
+        }
+        for (int i = 0; i < rows.size(); i++) {
+            Row row = rows.get(i);
+            row.setTempRowNumber(i);
+        }
+        rows.addAll(rowArrayList);
+        List<Column> columnArrayList = new ArrayList<>();
+        //获取非复制列的数据
+        for (Column column : columns) {
+            int columnKey = column.getColumnKey();
+            if (columnKey - 1 >= firstColumn && columnKey - 1 <= lastColumn) {
+                columnArrayList.add(column);
+            }
+        }
+
+        List<List<Column>> partition = ListUtil.partition(columnArrayList, fenceDataSize);
+        List<Column> headColumnList = partition.get(0);
+        //处理数据
+        for (int i = 1; i < partition.size(); i++) {
+            List<Column> dataList = partition.get(i);
+            Set<Column> dataSet = new HashSet<>(dataList);
+            for (int j = 0; j < rowSize; j++) {
+                Row row = rows.get(j);
+                Map<Column, Cell> columnCellMap = rowColCellMap.get(row);
+                Map<Column, Cell> newColumnCellMap = Optional.ofNullable(rowColCellMap.get(row))
+                        .map(map -> map.entrySet().stream()
+                                .filter(entry -> dataSet.contains(entry.getKey()))
+                                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))
+                        )
+                        .orElseGet(HashMap::new);
+                for (Column column1 : columnCellMap.keySet()) {
+                    if (copyColumnList.contains(column1)) {
+                        newColumnCellMap.put(column1, columnCellMap.get(column1));
+                    }
+                }
+                Map<Column, Cell> resultColumnCellMap = new HashMap<>();
+                for (Column column : newColumnCellMap.keySet()) {
+                    if (copyColumnList.contains(column)) {
+                        resultColumnCellMap.put(column, newColumnCellMap.get(column));
+                        continue;
+                    }
+                    int index = dataList.indexOf(column);
+                    resultColumnCellMap.put(headColumnList.get(index), newColumnCellMap.get(column));
+                }
+                int finalI = i;
+
+                List<Row> rowList = rows
+                        .stream()
+                        .filter(item -> item.getTempRowNumber() == row.getTempRowNumber() + rowSize * finalI)
+                        .collect(Collectors.toList());
+                rowColCellMap.put(rowList.get(0), resultColumnCellMap);
+            }
+        }
+
+        //将复制行和复制数据组合
+        List<Column> beforeFirst = new ArrayList<>();
+        List<Column> afterLast = new ArrayList<>();
+        for (Column column : copyColumnList) {
+            int columnKey = column.getColumnKey() - 1;
+            if (columnKey < firstColumn) beforeFirst.add(column);
+            else if (columnKey > lastColumn) afterLast.add(column);
+        }
+        List<Column> resultColumn = new ArrayList<>(beforeFirst);
+
+        int addedCount = 0;
+        for (Column column : columns) {
+            int columnKey = column.getColumnKey() - 1;
+            if (columnKey >= firstColumn && columnKey <= lastColumn) {
+                resultColumn.add(column);
+                if (addedCount == 0) {
+                    columnList.setColMinNum(resultColumn.indexOf(column));
+                }
+                if (++addedCount == fenceDataSize) {
+                    columnList.setColMaxNum(resultColumn.indexOf(column));
+                    break;
+                }
+            }
+        }
+
+        resultColumn.addAll(afterLast);
+        Set<Row> rowSet = rowColCellMap.keySet();
+        for (Row row : rowSet) {
+            Map<Column, Cell> columnCellMap = rowColCellMap.get(row);
+            columnCellMap.keySet().removeIf(column -> !resultColumn.contains(column));
+        }
+        ColFillBlank(columnList, rowColCellMap, resultColumn);
+
+        List<Column> allColumn = newColumnList.stream()
+                .sorted(Comparator.comparing(Column::getColumnKey)
+                        .thenComparing(Column::getTempColumnNumber))
+                .collect(Collectors.toList());
+
+        List<Column> collected = allColumn.stream()
+                .filter(item -> !resultColumn.contains(item))
+                .collect(Collectors.toList());
+        resultColumn.addAll(collected);
+
+        rowColCellMap.putAll(rowMapHashMap);
+        rows.addAll(rowNoNeed);
+        report.setRows(rows.stream().filter(Objects::nonNull).collect(Collectors.toList()));
+        report.setColumns(resultColumn);
+        report.setRowColCellMap(rowColCellMap);
+    }
+
+    private void rowChoice(Report report, ColumnList columnList, List<Column> columns
+            , int fenceNum, List<Row> rows, List<Row> copyRowList, Map<Row
+            , Map<Column, Cell>> rowColCellMap, int firstRow, int lastRow
+            , Map<Row, Map<Column, Cell>> rowMapHashMap
+            , List<Row> rowNoNeed, int fenceDataSize) {
+        //分多少栏
+        int columnSize = columns.size();
+        List<Column> columnArrayList = new ArrayList<>();
+        //造列
+        for (int i = 0; i < fenceNum - 1; i++) {
+            for (int j = 0; j < columnSize; j++) {
+                Column column = new Column(new ArrayList<>());
+                column.setTempColumnNumber(columns.size() * (i + 1) + j);
+                columnArrayList.add(column);
+            }
+        }
+        //给列添加标识
+        for (int i = 0; i < columns.size(); i++) {
+            Column column = columns.get(i);
+            column.setTempColumnNumber(i);
+        }
+        columns.addAll(columnArrayList);
+        //排除复制行
+        List<Row> rowArrayList = new ArrayList<>();
+        for (Row row : rows) {
+            int i = parseRowNum(row);
+            if (i >= firstRow && i <= lastRow) {
+                rowArrayList.add(row);
+            }
+        }
+
+        List<List<Row>> partition = ListUtil.partition(rowArrayList, fenceDataSize);
+        List<Row> rowList = partition.get(0);
+
+        for (Row row : copyRowList) {
+            if (rowColCellMap.containsKey(row)) {
+                Map<Column, Cell> columnCellMap = rowColCellMap.get(row);
+                Set<Column> columnSet = columnCellMap.keySet();
+                Map<Column, Cell> newColumnCellMap = new HashMap<>();
+                for (int i = 0; i < fenceNum - 1; i++) {
+                    int num;
+
+                    for (Column column : columnSet) {
+                        int finalI = i + 1;
+                        num = columns.indexOf(column);
+                        int finalNum = num;
+                        List<Column> collected = columns.stream().filter(item -> item.getTempColumnNumber() == (columnSize * finalI + finalNum))
+                                .collect(Collectors.toList());
+                        newColumnCellMap.put(collected.get(0), columnCellMap.get(columns.get(num)));
+                    }
+
+                }
+                columnCellMap.putAll(newColumnCellMap);
+            }
+        }
+
+        //处理数据
+        for (int i = 1; i < partition.size(); i++) {
+            List<Row> list = partition.get(i);
+
+            for (int j = 0; j < list.size(); j++) {
+                Row row1 = rowList.get(j);
+                Map<Column, Cell> cellMap = rowColCellMap.get(list.get(j));
+                for (Column column : cellMap.keySet()) {
+                    Map<Column, Cell> columnCellMap = rowColCellMap.get(row1);
+                    int finalI = i;
+
+                    List<Column> collected = columns.stream().filter(item -> item.getTempColumnNumber() == (columnSize * finalI + column.getTempColumnNumber()))
+                            .collect(Collectors.toList());
+
+                    columnCellMap.put(collected.get(0), cellMap.get(column));
+                }
+
+
+            }
+        }
+        //将复制行和复制数据组合
+        List<Row> beforeFirst = new ArrayList<>();
+        List<Row> afterLast = new ArrayList<>();
+        for (Row row : copyRowList) {
+            int rowNum = parseRowNum(row);
+            if (rowNum < firstRow) beforeFirst.add(row);
+            else if (rowNum > lastRow) afterLast.add(row);
+        }
+        List<Row> resultRow = new ArrayList<>(beforeFirst);
+
+        int addedCount = 0;
+        for (Row row : rows) {
+
+            int rowNum = parseRowNum(row);
+            if (rowNum >= firstRow && rowNum <= lastRow) {
+                resultRow.add(row);
+                if (addedCount == 0) {
+                    columnList.setRowMinNum(resultRow.indexOf(row));
+                }
+                if (++addedCount == fenceDataSize) {
+                    columnList.setRowMaxNum(resultRow.indexOf(row));
+                    break;
+                }
+            }
+        }
+
+        resultRow.addAll(afterLast);
+        rowColCellMap.keySet().removeIf(row -> !resultRow.contains(row));
+        rowColCellMap.putAll(rowMapHashMap);
+        resultRow.addAll(rowNoNeed.stream()
+                .filter(item -> !copyRowList.contains(item))
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList()));
+        report.setRows(resultRow);
+        report.setColumns(columns);
+        report.setRowColCellMap(rowColCellMap);
+    }
+
+    private static void ColFillBlank(ColumnList columnList, Map<Row, Map<Column, Cell>> rowColCellMap, List<Column> resultColumn) {
+        //补充空白格
+        if (columnList.isFillEmptyRows()) {
+            for (Row row : rowColCellMap.keySet()) {
+                Map<Column, Cell> columnCellMap = rowColCellMap.get(row);
+                Set<Column> columnSet = columnCellMap.keySet();
+                List<Column> collected = resultColumn.stream()
+                        .filter(column -> !columnSet.contains(column))
+                        .collect(Collectors.toList());
+                for (Column column : collected) {
+                    columnCellMap.put(column, new Cell());
+                }
+            }
+        }
+    }
+
+    @NotNull
+    private static List<Integer> getCopyCollect(String copyCol) {
+        if (StringUtil.isEmpty(copyCol)) {
+            return Collections.emptyList();
+        }
+        String[] split = copyCol.split(",");
+        List<String> list = new ArrayList<>(split.length);
+        for (String string : split) {
+            if (string.contains("-")) {
+                String[] strings = string.split("-");
+                list.addAll(Arrays.asList(strings));
+            }
+            list.add(string);
+        }
+        List<Integer> collect = new ArrayList<>();
+        try {
+            collect = list.stream()
+                    .map(Integer::valueOf)
+                    .map(item -> {
+
+                        if (item >= 1) {
+                            return item - 1;
+                        }
+                        return null;
+                    })
+                    .filter(Objects::nonNull).sorted().collect(Collectors.toList());
+
+        } catch (NumberFormatException e) {
+            throw new RuntimeException(e);
+        }
+        //复制列的列数并排序
+        return collect;
+    }
+
+    private int parseRowNum(Row row) {
+        return Integer.parseInt(row.getRowKey().replace('r', ' ').trim()) - 1;
+    }
+
+    private void formulaList(Cell formulaCell, Formula formula, Report report) {
+        String function = formula.getFormula();
+        int endRow = formula.getRowNumber();
+        int endCol = formula.getColNumber();
+        Map<String, List<String>> functionName = new LinkedHashMap<>();
+        Map<String, Map<Integer, Map<Integer, String>>> cellNameMap = formula.getCellName();
+        for (String name : formula.getCellNameList()) {
+            Map<Integer, Map<Integer, String>> cellName = cellNameMap.get(name) != null ? cellNameMap.get(name) : new HashMap<>();
+            //函数只支持左上角和右上角
+            List<Integer> rowList = new ArrayList<>(cellName.keySet()).stream().filter(e -> endRow >= e).collect(Collectors.toList());
+            List<String> leftTopList = new ArrayList<>();
+            List<String> rightTopList = new ArrayList<>();
+            List<Integer> delRow = new ArrayList<>();
+            for (Integer row : rowList) {
+                Map<Integer, String> colMap = cellName.get(row) != null ? cellName.get(row) : new HashMap<>();
+                List<Integer> leftTopCol = new ArrayList<>();
+                List<Integer> rightTopCol = new ArrayList<>();
+                for (Integer col : colMap.keySet()) {
+                    String functionCellName = colMap.get(col);
+                    if (StringUtil.isEmpty(functionCellName)) {
+                        continue;
+                    }
+                    if (endCol >= col) {
+                        leftTopList.add(functionCellName);
+                        leftTopCol.add(col);
+                    } else {
+                        rightTopList.add(functionCellName);
+                        rightTopCol.add(col);
+                    }
+                }
+                if (!leftTopCol.isEmpty()) {
+                    leftTopCol.forEach(colMap.keySet()::remove);
+                } else {
+                    rightTopCol.forEach(colMap.keySet()::remove);
+                }
+                cellName.put(row, colMap);
+                if (colMap.isEmpty()) {
+                    delRow.add(row);
+                }
+            }
+            delRow.forEach(cellName.keySet()::remove);
+            if (!leftTopList.isEmpty() || !rightTopList.isEmpty()) {
+                functionName.put(name, !leftTopList.isEmpty() ? leftTopList : rightTopList);
+            }
+        }
+        if (!functionName.isEmpty()) {
+            for (String name : functionName.keySet()) {
+                List<String> functionNameList = functionName.get(name);
+                if (functionNameList.size() > 255) {
+                    function = function.replaceAll(name, functionNameList.get(0) + ":" + functionNameList.get(functionNameList.size() - 1));
+                } else {
+                    function = function.replaceAll(name, String.join(",", functionNameList));
+                }
+            }
+            formulaCell.getCellData().setF(function);
+        }
+    }
+
+    private void rebuild(ReportDefinition report) {
+        List<CellDefinition> cells = report.getCells();
+        Map<String, CellDefinition> cellsMap = new HashMap<>();
+        Map<String, CellDefinition> cellsRowColMap = new HashMap<>();
+        for (CellDefinition cell : cells) {
+            cellsMap.put(cell.getName(), cell);
+            int rowNum = cell.getRowNumber();
+            int colNum = cell.getColumnNumber();
+            int rowSpan = cell.getRowSpan() > 0 ? cell.getRowSpan() : 1;
+            int colSpan = cell.getColSpan() > 0 ? cell.getColSpan() : 1;
+            int rowEnd = rowNum + rowSpan;
+            int colEnd = colNum + colSpan;
+            for (int i = rowNum; i < rowEnd; i++) {
+                cellsRowColMap.put(i + "," + colNum, cell);
+            }
+            for (int i = colNum; i < colEnd; i++) {
+                cellsRowColMap.put(rowNum + "," + i, cell);
+            }
+        }
+        for (CellDefinition cell : cells) {
+            int rowNumber = cell.getRowNumber();
+            int colNumber = cell.getColumnNumber();
+            Value value = cell.getValue();
+            boolean isData = value instanceof DatasetValue;
+
+            String leftType = cell.getLeftType();
+            String leftParentCellName = cell.getLeftParentCellName();
+            CellDefinition leftTargetCell = cellsMap.get(leftParentCellName);
+            if (leftTargetCell == null) {
+                if (colNumber > 1) {
+                    leftTargetCell = cellsRowColMap.get(rowNumber + "," + (colNumber - 1));
+                    boolean leftData = false;
+                    if (isData) {
+                        for (int i = colNumber; i > 0; i--) {
+                            CellDefinition definition = cellsRowColMap.get(rowNumber + "," + (i - 1));
+                            if (definition != null) {
+                                Value definitionValue = definition.getValue();
+                                if (definitionValue instanceof DatasetValue) {
+                                    leftTargetCell = definition;
+                                    leftData = true;
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                    if (!leftData && Objects.equals(UniverDataEnum.cellRoot.getName(), leftParentCellName)) {
+                        leftTargetCell = null;
+                    }
+                }
+            }
+            cell.setLeftParentCell(leftTargetCell);
+
+            String topType = cell.getTopType();
+            String topParentCellName = cell.getTopParentCellName();
+            CellDefinition topTargetCell = cellsMap.get(topParentCellName);
+            if (topTargetCell == null) {
+                if (rowNumber > 1) {
+                    topTargetCell = cellsRowColMap.get((rowNumber - 1) + "," + colNumber);
+                    boolean topData = false;
+                    if (isData) {
+                        for (int i = rowNumber; i > 0; i--) {
+                            CellDefinition definition = cellsRowColMap.get((i - 1) + "," + colNumber);
+                            if (definition != null) {
+                                Value definitionValue = definition.getValue();
+                                if (definitionValue instanceof DatasetValue) {
+                                    topTargetCell = definition;
+                                    topData = true;
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                    if (!topData && Objects.equals(UniverDataEnum.cellRoot.getName(), topParentCellName)) {
+                        topTargetCell = null;
+                    }
+                }
+            }
+            cell.setTopParentCell(topTargetCell);
+
+            if (isData) {
+                DatasetValue datasetValue = (DatasetValue) value;
+                AggregateType aggregate = datasetValue.getAggregate();
+                List<AggregateType> aggregateType = ImmutableList.of(AggregateType.select, AggregateType.group);
+                if (Objects.equals(topType, UniverDataEnum.cellNone.getName()) && Objects.equals(leftType, UniverDataEnum.cellNone.getName())) {
+                    if (!aggregateType.contains(aggregate)) {
+                        cell.setTopParentCell(null);
+                        cell.setLeftParentCell(null);
+                    }
+                }
+            }
+        }
+    }
+
+    private Map<String, Integer> fillEmptyRows(Map<Integer, Map<Integer, Integer>> fillRowMap) {
+        Map<String, Integer> fillRow = new HashMap<>();
+        for (Integer row : fillRowMap.keySet()) {
+            Map<Integer, Integer> columnMap = fillRowMap.get(row);
+            int max = 0;
+            String maxName = "";
+            for (Integer column : columnMap.keySet()) {
+                int rowNum = columnMap.get(column);
+                if (rowNum >= max) {
+                    CellReference reference = new CellReference(row, column);
+                    maxName = reference.formatAsString();
+                    max = rowNum;
+                }
+            }
+            fillRow.put(maxName, max);
+        }
+        return fillRow;
+    }
+
+    //赋值左、上父格
+    private void rebuildReportDefinition(ReportDefinition reportDefinition) {
+        List<CellDefinition> cells = reportDefinition.getCells();
+        for (CellDefinition cell : cells) {
+            List<String> rowName = new ArrayList<>();
+            addRowChildCell(cell, cell, rowName);
+            Set<String> row = new HashSet<>(rowName);
+            List<String> columnName = new ArrayList<>();
+            addColumnChildCell(cell, cell, columnName);
+            Set<String> column = new HashSet<>(columnName);
+            if (row.size() < rowName.size() || column.size() < columnName.size()) {
+                throw new DataException(MsgCode.FA106.get());
+            }
+        }
+        for (CellDefinition cell : cells) {
+            Expand expand = cell.getExpand();
+            switch (expand) {
+                case Down:
+                    DownCellbuilder downCellbuilder = new DownCellbuilder();
+                    downCellbuilder.buildParentCell(cell, cells);
+                    break;
+                case Right:
+                    RightCellbuilder rightCellbuilder = new RightCellbuilder();
+                    rightCellbuilder.buildParentCell(cell, cells);
+                    break;
+            }
+        }
+    }
+
+    //添加上父格
+    private static void addRowChildCell(CellDefinition cell, CellDefinition childCell, List<String> rowName) {
+        CellDefinition leftCell = cell.getLeftParentCell();
+        if (leftCell == null) {
+            return;
+        }
+        if (rowName.contains(leftCell.getName())) {
+            rowName.add(leftCell.getName());
+            return;
+        }
+        rowName.add(leftCell.getName());
+        List<CellDefinition> childrenCells = leftCell.getRowChildrenCells();
+        childrenCells.add(childCell);
+        addRowChildCell(leftCell, childCell, rowName);
+    }
+
+    //添加左父格
+    private static void addColumnChildCell(CellDefinition cell, CellDefinition childCell, List<String> columnName) {
+        CellDefinition topCell = cell.getTopParentCell();
+        if (topCell == null) {
+            return;
+        }
+        if (columnName.contains(topCell.getName())) {
+            columnName.add(topCell.getName());
+            return;
+        }
+        columnName.add(topCell.getName());
+        List<CellDefinition> childrenCells = topCell.getColumnChildrenCells();
+        childrenCells.add(childCell);
+        addColumnChildCell(topCell, childCell, columnName);
+    }
+
+    //解析函数,获取所在的格子
+    private static void formulaName(String formulaText, List<CellRangeAddress> list) {
+        List<String> splitList = ImmutableList.of(",", "=", ">", "<", "\\*", "\\+", "-", "/", "\\(", "\\)", "<>");
+        formulaName(formulaText, splitList, 0, list);
+    }
+
+    //函数,获取所在的格子
+    private static void formulaName(String formulaText, List<String> splitList, int index, List<CellRangeAddress> list) {
+        if (index > splitList.size() - 1) {
+            return;
+        }
+        String formula = splitList.get(index);
+        String[] strings = formulaText.split(formula);
+        for (String cell : strings) {
+            if (StringUtil.isEmpty(cell)) {
+                continue;
+            }
+            try {
+                CellRangeAddress cellRange = CellRangeAddress.valueOf(cell);
+                if (!list.contains(cellRange)) {
+                    list.add(cellRange);
+                }
+            } catch (Exception ignored) {
+            }
+            formulaName(cell, splitList, index + 1, list);
+        }
+    }
+
+    //函数区间的格子
+    private static List<CellReference> getCellsRange(int startRow, int endRow, int startCol, int endCol) {
+        int rangeStartRow = startRow;
+        int rangeStartCol = startCol;
+        int rangeEndRow = endRow;
+        int rangeEndCol = endCol;
+        if (startRow > endRow || startCol > endCol) {
+            rangeStartRow = endRow;
+            rangeStartCol = endCol;
+            rangeEndRow = startRow;
+            rangeEndCol = startCol;
+        }
+        List<CellReference> referenceList = new ArrayList<>();
+        if (rangeStartRow >= 0) {
+            for (int rowNum = rangeStartRow; rowNum <= rangeEndRow; rowNum++) {
+                for (int colNum = rangeStartCol; colNum <= rangeEndCol; colNum++) {
+                    CellReference reference = new CellReference(rowNum, colNum);
+                    referenceList.add(reference);
+                }
+            }
+        }
+        return referenceList;
+    }
+
+    private static void resource(String sheet, Map<String, Map<Integer, Map<Integer, String>>> nameMap, List<UniverResource> resources) {
+        //条件
+        format(sheet, nameMap, resources);
+        //数据验证
+        dataValidation(sheet, nameMap, resources);
+        //数据验证
+        filter(sheet, nameMap, resources);
+    }
+
+    //调整数据格式、数据管理的所在格子
+    private static List<UniverSheetRange> resourceRange(Map<String, Map<Integer, Map<Integer, String>>> nameMap, List<UniverSheetRange> sheetRanges) {
+        List<UniverSheetRange> rangeList = new ArrayList<>();
+        for (UniverSheetRange sheetRange : sheetRanges) {
+            int startRow = sheetRange.getStartRow();
+            int endRow = sheetRange.getEndRow();
+            int startCol = sheetRange.getStartColumn();
+            int endCol = sheetRange.getEndColumn();
+            List<CellReference> cellReferenceList = getCellsRange(startRow, endRow, startCol, endCol);
+            for (CellReference cellReference : cellReferenceList) {
+                String referenceName = cellReference.formatAsString();
+                List<String> nameList = new ArrayList<>();
+                Map<Integer, Map<Integer, String>> cellMap = nameMap.get(referenceName) != null ? nameMap.get(referenceName) : new HashMap<>();
+                for (Integer row : cellMap.keySet()) {
+                    Map<Integer, String> colMap = cellMap.get(row) != null ? cellMap.get(row) : new HashMap<>();
+                    for (Integer col : colMap.keySet()) {
+                        String name = colMap.get(col);
+                        if (StringUtil.isEmpty(name)) {
+                            continue;
+                        }
+                        if (!nameList.contains(name)) {
+                            UniverSheetRange range = JsonUtil.getJsonToBean(sheetRange, UniverSheetRange.class);
+                            range.setStartRow(row);
+                            range.setStartColumn(col);
+                            range.setEndRow(range.getStartRow());
+                            range.setEndColumn(range.getStartColumn());
+                            rangeList.add(range);
+                            nameList.add(name);
+                        }
+                    }
+                }
+            }
+        }
+        return rangeList.isEmpty() ? sheetRanges : rangeList;
+    }
+
+    //处理悬浮图表
+    private static Map<String, List<UniverDataConfig>> floatEchart(String unitId, List<UniverResource> resources, Map<String, UniverDataConfig> floatEchart) {
+        UniverResource drawing = resources.stream().filter(t -> ResourceEnum.SHEET_DRAWING_PLUGIN.name().equals(t.getName())).findFirst().orElse(null);
+        Map<String, UniverResourceData> drawingMap = new HashMap<>();
+        Map<String, List<UniverDataConfig>> echartMap = new HashMap<>();
+        if (drawing != null && ObjectUtil.isNotEmpty(drawing.getData())) {
+            Map<String, Object> data = JsonUtil.stringToMap(drawing.getData());
+            data.forEach((key, value) -> {
+                drawingMap.put(key, JsonUtil.getJsonToBean(value, UniverResourceData.class));
+            });
+            for (String sheet : drawingMap.keySet()) {
+                UniverResourceData resourceData = drawingMap.get(sheet);
+                List<String> orderList = resourceData.getOrder();
+                Map<String, UniverDrawing> dataMap = resourceData.getData();
+                List<UniverDataConfig> echartList = new ArrayList<>();
+                for (String order : orderList) {
+                    UniverDrawing univerDrawing = dataMap.get(order);
+                    if (univerDrawing == null) {
+                        continue;
+                    }
+                    univerDrawing.setUnitId(unitId);
+                    UniverDataConfig univerDataConfig = floatEchart.get(order);
+                    if (univerDataConfig != null) {
+                        UniverDataConfig option = univerDataConfig.getOption() != null ? univerDataConfig.getOption() : new UniverDataConfig();
+                        univerDataConfig.setDrawingId(univerDrawing.getDrawingId());
+                        univerDataConfig.setUnitId(univerDrawing.getUnitId());
+                        univerDataConfig.setSubUnitId(univerDrawing.getSubUnitId());
+                        univerDataConfig.setSummaryType(option.getSummaryType());
+                        univerDataConfig.setClassifyNameField(option.getClassifyNameField());
+                        univerDataConfig.setSeriesNameField(option.getSeriesNameField());
+                        univerDataConfig.setSeriesDataField(option.getSeriesDataField());
+                        univerDataConfig.setMaxField(option.getMaxField());
+                        echartList.add(univerDataConfig);
+                    }
+                }
+                echartMap.put(sheet, echartList);
+            }
+//            drawing.setData(JSON.toJSONString(JSON.toJSON(drawingMap)));
+        }
+        return echartMap;
+    }
+
+    //处理单元格图表
+    private static Map<String, List<UniverDataConfig>> cellEchart(Map<String, UniverDataConfig> cellEchart, String unitId) {
+        Map<String, List<UniverDataConfig>> echartMap = new HashMap<>();
+        for (String key : cellEchart.keySet()) {
+            UniverDataConfig univerDataConfig = cellEchart.get(key);
+            if (univerDataConfig != null) {
+                UniverDataConfig option = univerDataConfig.getOption();
+                String sheet = univerDataConfig.getSheet();
+                if (option != null) {
+                    univerDataConfig.setUnitId(unitId);
+                    univerDataConfig.setSubUnitId(sheet);
+                    univerDataConfig.setSummaryType(option.getSummaryType());
+                    univerDataConfig.setClassifyNameField(option.getClassifyNameField());
+                    univerDataConfig.setSeriesNameField(option.getSeriesNameField());
+                    univerDataConfig.setSeriesDataField(option.getSeriesDataField());
+                    univerDataConfig.setMaxField(option.getMaxField());
+                    univerDataConfig.setType(CellDataEnum.cellChart.name());
+                    List<UniverDataConfig> echartList = echartMap.get(sheet) != null ? echartMap.get(sheet) : new ArrayList<>();
+                    echartList.add(univerDataConfig);
+                    echartMap.put(sheet, echartList);
+                }
+            }
+        }
+        return echartMap;
+    }
+
+    //解析数据格式
+    private static void format(String sheet, Map<String, Map<Integer, Map<Integer, String>>> nameMap, List<UniverResource> resources) {
+        UniverResource formatting = resources.stream().filter(t -> ResourceEnum.SHEET_CONDITIONAL_FORMATTING_PLUGIN.name().equals(t.getName())).findFirst().orElse(null);
+        Map<String, List<UniverResourceData>> foramtMap = new HashMap<>();
+        if (formatting != null && ObjectUtil.isNotEmpty(formatting.getData())) {
+            Map<String, Object> data = JsonUtil.stringToMap(formatting.getData());
+            data.forEach((key, value) -> {
+                foramtMap.put(key, JsonUtil.getJsonToList(value, UniverResourceData.class));
+            });
+            if (foramtMap.get(sheet) != null) {
+                List<UniverResourceData> dataList = foramtMap.get(sheet);
+                for (UniverResourceData resourceData : dataList) {
+                    List<UniverSheetRange> sheetRanges = resourceData.getRanges();
+                    List<UniverSheetRange> rangesList = resourceRange(nameMap, sheetRanges);
+                    resourceData.setRanges(rangesList);
+                }
+            }
+            formatting.setData(JSON.toJSONString(JSON.toJSON(foramtMap)));
+        }
+    }
+
+    //解析数据验证
+    private static void dataValidation(String sheet, Map<String, Map<Integer, Map<Integer, String>>> nameMap, List<UniverResource> resources) {
+        UniverResource validation = resources.stream().filter(t -> ResourceEnum.SHEET_DATA_VALIDATION_PLUGIN.name().equals(t.getName())).findFirst().orElse(null);
+        Map<String, List<UniverResourceData>> validationMap = new HashMap<>();
+        if (validation != null && ObjectUtil.isNotEmpty(validation.getData())) {
+            Map<String, Object> data = JsonUtil.stringToMap(validation.getData());
+            data.forEach((key, value) -> {
+                validationMap.put(key, JsonUtil.getJsonToList(value, UniverResourceData.class));
+            });
+            if (validationMap.get(sheet) != null) {
+                List<UniverResourceData> dataList = validationMap.get(sheet);
+                for (UniverResourceData resourceData : dataList) {
+                    List<UniverSheetRange> sheetRanges = resourceData.getRanges();
+                    List<UniverSheetRange> rangesList = resourceRange(nameMap, sheetRanges);
+                    resourceData.setRanges(rangesList);
+                }
+            }
+            validation.setData(JSON.toJSONString(JSON.toJSON(validationMap)));
+        }
+    }
+
+
+    private static void filter(String sheet, Map<String, Map<Integer, Map<Integer, String>>> nameMap, List<UniverResource> resources) {
+        UniverResource filter = resources.stream().filter(t -> ResourceEnum.SHEET_FILTER_PLUGIN.name().equals(t.getName())).findFirst().orElse(null);
+        Map<String, UniverResourceData> filterMap = new HashMap<>();
+        if (filter != null && ObjectUtil.isNotEmpty(filter.getData())) {
+            Map<String, Object> data = JsonUtil.stringToMap(filter.getData());
+            data.forEach((key, value) -> {
+                filterMap.put(key, JsonUtil.getJsonToBean(value, UniverResourceData.class));
+            });
+            if (filterMap.get(sheet) != null) {
+                UniverResourceData resourceData = filterMap.get(sheet);
+                if (resourceData != null) {
+                    UniverSheetRange sheetRange = resourceData.getRef();
+                    List<UniverSheetRange> rangesList = resourceRange(nameMap, ImmutableList.of(sheetRange));
+                    Map<Integer, List<UniverSheetRange>> rangesMap = rangesList.stream().collect(Collectors.groupingBy(UniverSheetRange::getStartRow));
+                    int startRow = Collections.min(rangesMap.keySet());
+                    int startCol = Collections.min(rangesMap.get(startRow).stream().map(UniverSheetRange::getStartColumn).collect(Collectors.toList()));
+                    int endRow = Collections.max(rangesMap.keySet());
+                    int endCol = Collections.max(rangesMap.get(endRow).stream().map(UniverSheetRange::getEndColumn).collect(Collectors.toList()));
+                    UniverSheetRange range = JsonUtil.getJsonToBean(sheetRange, UniverSheetRange.class);
+                    range.setStartRow(startRow);
+                    range.setStartColumn(startCol);
+                    range.setEndRow(endRow);
+                    range.setEndColumn(endCol);
+                    resourceData.setRef(range);
+                }
+                filter.setData(JSON.toJSONString(JSON.toJSON(filterMap)));
+            }
+        }
+
+    }
+}

+ 1148 - 0
jnpf-datareport-univer-common/src/main/java/jnpf/util/UniverExcel.java

@@ -0,0 +1,1148 @@
+package jnpf.util;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.codec.Base64;
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.Method;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.io.Files;
+import jnpf.constant.MsgCode;
+import jnpf.entity.FileParameter;
+import jnpf.enums.*;
+import jnpf.exception.DataException;
+import jnpf.univer.chart.UniverChartModel;
+import jnpf.univer.data.resource.*;
+import jnpf.univer.model.UniverWorkBook;
+import jnpf.univer.properties.UniverBody;
+import jnpf.univer.properties.UniverBodyConfig;
+import jnpf.univer.properties.UniverProperties;
+import jnpf.univer.resources.UniverResource;
+import jnpf.univer.resources.UniverResourceData;
+import jnpf.univer.sheet.*;
+import jnpf.univer.style.UniverStyle;
+import jnpf.univer.style.UniverStyleBorder;
+import jnpf.univer.style.UniverStyleTextDecoration;
+import jnpf.univer.style.UniverStyleTextRotation;
+import jnpf.util.excel.ExcelParser;
+import jnpf.util.excel.UniverHSSFExcel;
+import jnpf.util.excel.UniverXSSFExcel;
+import jnpf.util.type.RequestType;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.poi.common.usermodel.HyperlinkType;
+import org.apache.poi.ss.usermodel.Font;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.CellRangeAddressList;
+import org.apache.poi.xssf.model.StylesTable;
+import org.apache.poi.xssf.usermodel.*;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.awt.Color;
+import java.io.*;
+import java.util.List;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/9/29 下午5:17
+ */
+@Slf4j
+public class UniverExcel {
+
+    private static Map<String, ExcelParser> excelMap = ImmutableMap.of(
+            "xlsx", new UniverXSSFExcel(),
+            "xls", new UniverHSSFExcel()
+    );
+
+    public static UniverWorkBook formFile(MultipartFile file) throws IOException {
+        //todo 推荐使用xlsx方法
+        String fileName = file.getOriginalFilename();
+        String type = Files.getFileExtension(fileName);
+        ExcelParser excelParser = excelMap.get(type);
+        if (excelParser == null) {
+            throw new DataException(MsgCode.ETD110.get());
+        }
+        UniverWorkBook univerWorkBook = excelParser.formFile(file.getInputStream());
+        return univerWorkBook;
+    }
+
+    public static void downExcel(String snapshot, List<UniverChartModel> chartList, XSSFWorkbook workbook, List<String> sheetList) {
+        Map<UniverStyle, XSSFCellStyle> styleMap = new HashMap<>();
+        UniverWorkBook univerWorkBook = JsonUtil.getJsonToBean(snapshot, UniverWorkBook.class);
+
+        Map<String, UniverSheet> univerSheetMap = univerWorkBook.getSheets();
+        List<UniverResource> resources = univerWorkBook.getResources() != null ? univerWorkBook.getResources() : new ArrayList<>();
+        Map<String, String> sheetMap = new HashMap<>();
+        Map<XSSFCell, String> linkMap = new HashMap<>();
+        Map<String, List<UniverDrawing>> sheetDrawingMap = new HashMap<>();
+        Map<String, String> sheetMapReversed = univerSheetMap.entrySet().stream()
+                .collect(Collectors.toMap(
+                        Map.Entry::getKey,
+                        entry -> entry.getValue().getName()
+                ));
+
+        for (String sheetOrder : univerWorkBook.getSheetOrder()) {
+            UniverSheet univerSheet = univerSheetMap.get(sheetOrder);
+            if (ObjectUtil.isNotEmpty(univerSheet)) {
+                if (!sheetList.contains(sheetOrder)) {
+                    continue;
+                }
+                List<UniverSheetRange> mergeData = univerSheet.getMergeData();
+                String sheetName = univerSheet.getName();
+                XSSFSheet sheet = workbook.createSheet(sheetName);
+                sheetMap.put(sheetName, sheetOrder);
+                sheetMapReversed.put(sheetOrder, sheetName);
+                workbook.setSheetHidden(workbook.getSheetIndex(sheet), Objects.equals(univerSheet.getHidden(), 1));
+                Map<Integer, UniverSheetRowData> rowData = univerSheet.getRowData();
+                Map<Integer, UniverSheetColumnData> colData = univerSheet.getColumnData();
+                XSSFDrawing drawing = sheet.createDrawingPatriarch();
+                //冻结位置
+                UniverSheetFreeze freeze = univerSheet.getFreeze() != null ? univerSheet.getFreeze() : new UniverSheetFreeze();
+                sheet.createFreezePane(freeze.getStartColumn(), freeze.getStartRow());
+                List<UniverDrawing> drawingList = new ArrayList<>();
+                AtomicBoolean isHyperLink = new AtomicBoolean(false);
+                //遍历数据
+                univerSheet.getCellData().forEach((rowKey, sheetRow) -> {
+                    XSSFRow row = sheet.createRow(rowKey);
+                    UniverSheetRowData sheetRowData = rowData.get(rowKey);
+                    if (ObjectUtil.isNotEmpty(sheetRowData)) {
+                        row.setZeroHeight(Objects.equals(sheetRowData.getHd(), 1));
+                        if (ObjectUtil.isNotEmpty(sheetRowData.getH())) {
+                            row.setHeightInPoints(sheetRowData.getH());
+                        }
+                    }
+                    sheetRow.forEach((colKey, sheetCol) -> {
+                        UniverSheetRange range = mergeData.stream().filter(t -> Objects.equals(t.getStartRow(), rowKey) && Objects.equals(t.getStartColumn(), colKey)).findFirst().orElse(null);
+                        Object value = sheetCol.getV();
+                        Object formula = sheetCol.getF();
+                        Object style = sheetCol.getS();
+                        Object p = sheetCol.getP();
+                        UniverProperties properties = p != null ? JsonUtil.getJsonToBean(p, UniverProperties.class) : null;
+                        XSSFCell cell = row.createCell(colKey);
+                        UniverSheetColumnData columnData = colData.get(colKey);
+                        if (ObjectUtil.isNotEmpty(columnData)) {
+                            if (ObjectUtil.isNotEmpty(columnData.getW())) {
+                                sheet.setColumnWidth(colKey, (short) (columnData.getW() * 1.33 * 35));
+                            }
+                            sheet.setColumnHidden(colKey, Objects.equals(columnData.getHd(), 1));
+                        }
+                        boolean zxing = true;
+                        if (properties != null) {
+                            List<String> drawingsOrder = properties.getDrawingsOrder() != null ? properties.getDrawingsOrder() : new ArrayList<>();
+                            if (!drawingsOrder.isEmpty()) {
+                                zxing = false;
+                                //单元格图片、图表
+                                Map<String, UniverDrawing> drawings = properties.getDrawings() != null ? properties.getDrawings() : new HashMap<>();
+                                for (String order : drawingsOrder) {
+                                    UniverDrawing univerDrawing = drawings.get(order);
+                                    if (univerDrawing != null) {
+                                        UniverTransform sheetTransform = new UniverTransform();
+                                        UniverOffset form = new UniverOffset();
+                                        form.setRow(rowKey);
+                                        form.setColumn(colKey);
+                                        sheetTransform.setFrom(form);
+                                        UniverOffset to = new UniverOffset();
+                                        UniverSheetRange sheetRange = mergeData.stream().filter(t -> Objects.equals(t.getStartRow(), rowKey) && Objects.equals(t.getStartColumn(), colKey)).findFirst().orElse(null);
+                                        int rowSpan = sheetRange != null ? sheetRange.getEndRow() - sheetRange.getStartRow() + 1 : 1;
+                                        int colSpan = sheetRange != null ? sheetRange.getEndColumn() - sheetRange.getStartColumn() + 1 : 1;
+                                        to.setRow(form.getRow() + rowSpan);
+                                        to.setColumn(form.getColumn() + colSpan);
+                                        sheetTransform.setTo(to);
+                                        univerDrawing.setSheetTransform(sheetTransform);
+                                        drawingList.add(univerDrawing);
+                                    }
+                                }
+                            } else {
+                                UniverBody body = properties.getBody();
+                                if (body != null) {
+                                    isHyperLink.set(true);
+                                    cell.setCellType(CellType.STRING);
+                                    cell.setCellValue(body.getDataStream());
+                                    List<UniverBodyConfig> customRangesList = body.getCustomRanges() != null ? body.getCustomRanges() : new ArrayList<>();
+                                    for (UniverBodyConfig customRanges : customRangesList) {
+                                        UniverBodyConfig custom = customRanges.getProperties();
+                                        if (custom == null) {
+                                            continue;
+                                        }
+                                        linkMap.put(cell, custom.getUrl());
+                                    }
+                                }
+                            }
+                        }
+
+                        Integer type = ObjectUtil.isNotEmpty(formula) ? CellDataTypeEnum.Formula.getCode() : sheetCol.getT();
+                        Object dataValue = ObjectUtil.isNotEmpty(formula) ? formula : value;
+                        if (zxing) {
+                            if (ObjectUtil.isNotEmpty(dataValue)) {
+                                CellDataTypeEnum dataType = CellDataTypeEnum.getDataType(type);
+                                switch (dataType) {
+                                    case Number:
+                                        cell.setCellValue(Double.valueOf(dataValue.toString()));
+                                        cell.setCellType(CellType.NUMERIC);
+                                        break;
+                                    case Boolean:
+                                        cell.setCellValue(Boolean.valueOf(dataValue.toString()));
+                                        cell.setCellType(CellType.BOOLEAN);
+                                        break;
+                                    case Formula:
+                                        try {
+                                            cell.setCellFormula(dataValue.toString().substring(1));
+                                            cell.setCellType(CellType.FORMULA);
+                                        } catch (Exception e) {
+                                            cell.setCellValue(dataValue.toString());
+                                            cell.setCellType(CellType.STRING);
+                                        }
+                                        break;
+                                    default:
+                                        cell.setCellValue(dataValue.toString());
+                                        cell.setCellType(CellType.STRING);
+                                        break;
+                                }
+                            }
+                        }
+
+                        if (ObjectUtil.isNotEmpty(style)) {
+                            UniverStyle basicStyle = univerWorkBook.getStyles().get(style);
+                            if (ObjectUtil.isEmpty(basicStyle)) {
+                                basicStyle = JsonUtil.getJsonToBean(style, UniverStyle.class);
+                            }
+                            if (ObjectUtil.isNotEmpty(basicStyle)) {
+                                UniverStyleBorder bd = basicStyle.getBd();
+                                if (ObjectUtil.isNotEmpty(styleMap.get(basicStyle))) {
+                                    bdAnchor(bd, rowKey, colKey, range, drawing);
+                                    cell.setCellStyle(styleMap.get(basicStyle));
+                                } else {
+                                    XSSFCellStyle cellStyle = workbook.createCellStyle();
+                                    if (ObjectUtil.isNotEmpty(basicStyle.getBg()) && ObjectUtil.isNotEmpty(basicStyle.getBg().getRgb())) {
+                                        String bgGrb = basicStyle.getBg().getRgb();
+                                        XSSFColor color = color(bgGrb);
+                                        if (color != null) {
+                                            cellStyle.setFillForegroundColor(color);
+                                            cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+                                        }
+                                    }
+                                    if (ObjectUtil.isNotEmpty(bd)) {
+                                        if (ObjectUtil.isNotEmpty(bd.getT()) && ObjectUtil.isNotEmpty(bd.getT().getCl())) {
+                                            String bdt = bd.getT().getCl().getRgb();
+                                            if (ObjectUtil.isNotEmpty(bdt)) {
+                                                XSSFColor color = color(bdt);
+                                                if (color != null) {
+                                                    cellStyle.setTopBorderColor(color);
+                                                }
+                                            }
+                                            StyleTypeEnum bdStyle = StyleTypeEnum.getStyle(bd.getT().getS());
+                                            if (ObjectUtil.isNotEmpty(bdStyle)) {
+                                                cellStyle.setBorderTop(bdStyle.getBorderStyle());
+                                            }
+                                        }
+                                        if (ObjectUtil.isNotEmpty(bd.getL()) && ObjectUtil.isNotEmpty(bd.getL().getCl())) {
+                                            String bdl = bd.getL().getCl().getRgb();
+                                            if (ObjectUtil.isNotEmpty(bdl)) {
+                                                XSSFColor color = color(bdl);
+                                                if (color != null) {
+                                                    cellStyle.setLeftBorderColor(color);
+                                                }
+                                            }
+                                            StyleTypeEnum bdStyle = StyleTypeEnum.getStyle(bd.getL().getS());
+                                            if (ObjectUtil.isNotEmpty(bdStyle)) {
+                                                cellStyle.setBorderLeft(bdStyle.getBorderStyle());
+                                            }
+                                        }
+                                        if (ObjectUtil.isNotEmpty(bd.getB()) && ObjectUtil.isNotEmpty(bd.getB().getCl())) {
+                                            String bdb = bd.getB().getCl().getRgb();
+                                            if (ObjectUtil.isNotEmpty(bdb)) {
+                                                XSSFColor color = color(bdb);
+                                                if (color != null) {
+                                                    cellStyle.setBottomBorderColor(color);
+                                                }
+                                            }
+                                            StyleTypeEnum bdStyle = StyleTypeEnum.getStyle(bd.getB().getS());
+                                            if (ObjectUtil.isNotEmpty(bdStyle)) {
+                                                cellStyle.setBorderBottom(bdStyle.getBorderStyle());
+                                            }
+                                        }
+                                        if (ObjectUtil.isNotEmpty(bd.getR()) && ObjectUtil.isNotEmpty(bd.getR().getCl())) {
+                                            String bdr = bd.getR().getCl().getRgb();
+                                            if (ObjectUtil.isNotEmpty(bdr)) {
+                                                XSSFColor color = color(bdr);
+                                                if (color != null) {
+                                                    cellStyle.setRightBorderColor(color);
+                                                }
+                                            }
+                                            StyleTypeEnum bdStyle = StyleTypeEnum.getStyle(bd.getR().getS());
+                                            if (ObjectUtil.isNotEmpty(bdStyle)) {
+                                                cellStyle.setBorderRight(bdStyle.getBorderStyle());
+                                            }
+                                        }
+                                        bdAnchor(bd, rowKey, colKey, range, drawing);
+                                    }
+                                    HorizontalAlignment alignment = ObjectUtil.isNotEmpty(basicStyle.getHt()) ? HorizontalEnum.getHorizontalValue(basicStyle.getHt()) : null;
+                                    if (ObjectUtil.isNotEmpty(alignment)) {
+                                        cellStyle.setAlignment(alignment);
+                                    }
+                                    VerticalAlignment verticalValue = ObjectUtil.isNotEmpty(basicStyle.getVt()) ? VerticalEnum.getVerticalValue(basicStyle.getVt()) : null;
+                                    if (ObjectUtil.isNotEmpty(verticalValue)) {
+                                        cellStyle.setVerticalAlignment(verticalValue);
+                                    }
+                                    if (ObjectUtil.isNotEmpty(basicStyle.getN()) && ObjectUtil.isNotEmpty(basicStyle.getN().getPattern())) {
+                                        DataFormat format = workbook.createDataFormat();
+                                        cellStyle.setDataFormat(format.getFormat(basicStyle.getN().getPattern()));
+                                    }
+                                    if (ObjectUtil.isNotEmpty(basicStyle.getTb()) && Objects.equals(basicStyle.getTb(), 3)) {
+                                        cellStyle.setWrapText(true);
+                                    }
+                                    if (ObjectUtil.isNotEmpty(basicStyle.getTr())) {
+                                        UniverStyleTextRotation tr = basicStyle.getTr();
+                                        int v = tr.getV();
+                                        int rotation = tr.getA();
+                                        if (Objects.equals(v, 1)) {
+                                            rotation = -255;
+                                        }
+                                        cellStyle.setRotation((short) -rotation);
+                                    }
+                                    XSSFFont font = workbook.createFont();
+                                    if (ObjectUtil.isNotEmpty(basicStyle.getFf())) {
+                                        font.setFontName(basicStyle.getFf());
+                                    }
+                                    if (ObjectUtil.isNotEmpty(basicStyle.getFs())) {
+                                        font.setFontHeight(basicStyle.getFs());
+                                    }
+                                    if (ObjectUtil.isNotEmpty(basicStyle.getIt())) {
+                                        font.setItalic(Objects.equals(basicStyle.getIt(), 1));
+                                    }
+                                    if (ObjectUtil.isNotEmpty(basicStyle.getBl())) {
+                                        font.setBold(Objects.equals(basicStyle.getBl(), 1));
+                                    }
+                                    if (ObjectUtil.isNotEmpty(basicStyle.getCl()) && ObjectUtil.isNotEmpty(basicStyle.getCl().getRgb())) {
+                                        XSSFColor color = color(basicStyle.getCl().getRgb());
+                                        if (color != null) {
+                                            font.setColor(color);
+                                        }
+                                    }
+                                    if (ObjectUtil.isNotEmpty(basicStyle.getUl()) && ObjectUtil.isNotEmpty(basicStyle.getUl().getS())) {
+                                        font.setUnderline(Objects.equals(basicStyle.getUl().getS(), 1) ? Font.U_SINGLE : Font.U_NONE);
+                                    }
+                                    if (ObjectUtil.isNotEmpty(basicStyle.getSt()) && ObjectUtil.isNotEmpty(basicStyle.getSt().getS())) {
+                                        font.setStrikeout(Objects.equals(basicStyle.getSt().getS(), 1));
+                                    }
+                                    cellStyle.setFont(font);
+                                    cell.setCellStyle(cellStyle);
+                                    styleMap.put(basicStyle, cellStyle);
+                                }
+                            }
+                        }
+                    });
+                });
+                //合并单元格
+                for (UniverSheetRange region : new HashSet<>(mergeData)) {
+                    if (region.getEndRow() - region.getStartRow() == 0 && region.getEndColumn() - region.getStartColumn() == 0) {
+                        continue;
+                    }
+                    sheet.addMergedRegion(new CellRangeAddress(region.getStartRow(), region.getEndRow(), region.getStartColumn(), region.getEndColumn()));
+                }
+                sheetDrawingMap.put(sheetName, drawingList);
+            }
+        }
+        sheetMap.forEach((key, value) -> {
+            XSSFSheet sheet = workbook.getSheet(key);
+            if (sheet != null) {
+                List<UniverDrawing> drawingList = sheetDrawingMap.get(key) != null ? sheetDrawingMap.get(key) : new ArrayList<>();
+                XSSFDrawing drawing = sheet.getDrawingPatriarch();
+                //图片
+                drawing(value, resources, drawingList, drawing, workbook);
+                //条件格式
+                format(value, resources, sheet);
+                //数据有效性
+                dataValidation(value, resources, sheet);
+                //筛选
+                filter(value, resources, sheet);
+
+
+            }
+        });
+        //定义名称
+        definedName(resources, univerSheetMap, linkMap, workbook);
+    }
+
+
+    private static HyperlinkType getType(String url) {
+        // 兼容性检查:通过地址格式二次验证
+        if (url == null) return HyperlinkType.NONE;
+
+        if (url.startsWith("#")) {
+            return HyperlinkType.DOCUMENT;
+        } else if (url.startsWith("http://") || url.startsWith("https://")) {
+            return HyperlinkType.URL;
+        } else if (url.startsWith("mailto:")) {
+            return HyperlinkType.EMAIL;
+        } else if (url.contains("\\") || url.contains("/")) {
+            return HyperlinkType.FILE;
+        }
+        return HyperlinkType.NONE;
+    }
+
+    private static void bdAnchor(UniverStyleBorder bd, int rowKey, int colKey, UniverSheetRange range, XSSFDrawing drawing) {
+        if (ObjectUtil.isNotEmpty(bd)) {
+            if (ObjectUtil.isNotEmpty(bd.getTl_br()) && ObjectUtil.isNotEmpty(bd.getTl_br().getCl())) {
+                int startRow = rowKey;
+                int startCol = colKey;
+                int endRow = rowKey + 1;
+                int endCol = colKey + 1;
+                if (range != null) {
+                    endRow = range.getEndRow() + 1;
+                    endCol = range.getEndColumn() + 1;
+                }
+                XSSFClientAnchor anchor = new XSSFClientAnchor();
+                anchor.setRow1(startRow);
+                anchor.setCol1(startCol);
+                anchor.setRow2(endRow);
+                anchor.setCol2(endCol);
+                XSSFSimpleShape shape = drawing.createSimpleShape(anchor);
+                StyleTypeEnum bdStyle = StyleTypeEnum.getStyle(bd.getTl_br().getS());
+                if (ObjectUtil.isNotEmpty(bdStyle)) {
+                    shape.setShapeType(bdStyle.getBorderStyle().getCode());
+                }
+                String bdr = bd.getTl_br().getCl().getRgb();
+                if (ObjectUtil.isNotEmpty(bdr)) {
+                    XSSFColor color = color(bdr);
+                    if (color != null) {
+                        shape.setLineStyleColor(color.getRGB()[0], color.getRGB()[1], color.getRGB()[2]);
+                    }
+                }
+                shape.setShapeType(ShapeTypes.LINE);
+            }
+            if (ObjectUtil.isNotEmpty(bd.getTl_mr()) && ObjectUtil.isNotEmpty(bd.getTl_mr().getCl())) {
+                if (range != null) {
+                    int startRow = rowKey;
+                    int startCol = colKey;
+                    int endRow = (rowKey + range.getEndRow() + 1) / 2;
+                    int endCol = range.getEndColumn() + 1;
+                    XSSFClientAnchor anchor = new XSSFClientAnchor();
+                    anchor.setRow1(startRow);
+                    anchor.setCol1(startCol);
+                    anchor.setRow2(endRow);
+                    anchor.setCol2(endCol);
+                    XSSFSimpleShape shape = drawing.createSimpleShape(anchor);
+                    StyleTypeEnum bdStyle = StyleTypeEnum.getStyle(bd.getTl_mr().getS());
+                    if (ObjectUtil.isNotEmpty(bdStyle)) {
+                        shape.setShapeType(bdStyle.getBorderStyle().getCode());
+                    }
+                    String bdr = bd.getTl_mr().getCl().getRgb();
+                    if (ObjectUtil.isNotEmpty(bdr)) {
+                        XSSFColor color = color(bdr);
+                        if (color != null) {
+                            shape.setLineStyleColor(color.getRGB()[0], color.getRGB()[1], color.getRGB()[2]);
+                        }
+                    }
+                    shape.setShapeType(ShapeTypes.LINE);
+                }
+            }
+            if (ObjectUtil.isNotEmpty(bd.getTl_bc()) && ObjectUtil.isNotEmpty(bd.getTl_bc().getCl())) {
+                if (range != null) {
+                    int startRow = rowKey;
+                    int startCol = colKey;
+                    int endRow = range.getEndRow() + 1;
+                    int endCol = (colKey + range.getEndColumn() + 1) / 2;
+                    XSSFClientAnchor anchor = new XSSFClientAnchor();
+                    anchor.setRow1(startRow);
+                    anchor.setCol1(startCol);
+                    anchor.setRow2(endRow);
+                    anchor.setCol2(endCol);
+                    XSSFSimpleShape shape = drawing.createSimpleShape(anchor);
+                    StyleTypeEnum bdStyle = StyleTypeEnum.getStyle(bd.getTl_bc().getS());
+                    if (ObjectUtil.isNotEmpty(bdStyle)) {
+                        shape.setShapeType(bdStyle.getBorderStyle().getCode());
+                    }
+                    String bdr = bd.getTl_bc().getCl().getRgb();
+                    if (ObjectUtil.isNotEmpty(bdr)) {
+                        XSSFColor color = color(bdr);
+                        if (color != null) {
+                            shape.setLineStyleColor(color.getRGB()[0], color.getRGB()[1], color.getRGB()[2]);
+                        }
+                    }
+                    shape.setShapeType(ShapeTypes.LINE);
+                }
+            }
+            if (ObjectUtil.isNotEmpty(bd.getBl_tr()) && ObjectUtil.isNotEmpty(bd.getBl_tr().getCl())) {
+                int startRow = rowKey;
+                int startCol = colKey;
+                int endRow = rowKey + 1;
+                int endCol = colKey + 1;
+                if (range != null) {
+                    endRow = range.getEndRow() + 1;
+                    endCol = range.getEndColumn() + 1;
+                }
+                XSSFClientAnchor anchor = new XSSFClientAnchor();
+                anchor.setRow1(startRow);
+                anchor.setCol1(startCol);
+                anchor.setRow2(endRow);
+                anchor.setCol2(endCol);
+                XSSFSimpleShape shape = drawing.createSimpleShape(anchor);
+                StyleTypeEnum bdStyle = StyleTypeEnum.getStyle(bd.getBl_tr().getS());
+                if (ObjectUtil.isNotEmpty(bdStyle)) {
+                    shape.setShapeType(bdStyle.getBorderStyle().getCode());
+                }
+                String bdr = bd.getBl_tr().getCl().getRgb();
+                if (ObjectUtil.isNotEmpty(bdr)) {
+                    XSSFColor color = color(bdr);
+                    if (color != null) {
+                        shape.setLineStyleColor(color.getRGB()[0], color.getRGB()[1], color.getRGB()[2]);
+                    }
+                }
+                shape.setShapeType(ShapeTypes.LINE_INV);
+            }
+            if (ObjectUtil.isNotEmpty(bd.getBc_tr()) && ObjectUtil.isNotEmpty(bd.getBc_tr().getCl())) {
+                if (range != null) {
+                    int startRow = rowKey;
+                    int startCol = range.getStartColumn();
+                    int endRow = (rowKey + range.getEndRow() + 1) / 2;
+                    int endCol = range.getEndColumn() + 1;
+                    XSSFClientAnchor anchor = new XSSFClientAnchor();
+                    anchor.setRow1(startRow);
+                    anchor.setCol1(startCol);
+                    anchor.setRow2(endRow);
+                    anchor.setCol2(endCol);
+                    XSSFSimpleShape shape = drawing.createSimpleShape(anchor);
+                    StyleTypeEnum bdStyle = StyleTypeEnum.getStyle(bd.getBc_tr().getS());
+                    if (ObjectUtil.isNotEmpty(bdStyle)) {
+                        shape.setShapeType(bdStyle.getBorderStyle().getCode());
+                    }
+                    String bdr = bd.getBc_tr().getCl().getRgb();
+                    if (ObjectUtil.isNotEmpty(bdr)) {
+                        XSSFColor color = color(bdr);
+                        if (color != null) {
+                            shape.setLineStyleColor(color.getRGB()[0], color.getRGB()[1], color.getRGB()[2]);
+                        }
+                    }
+                    shape.setShapeType(ShapeTypes.LINE_INV);
+                }
+            }
+            if (ObjectUtil.isNotEmpty(bd.getMl_tr()) && ObjectUtil.isNotEmpty(bd.getMl_tr().getCl())) {
+                if (range != null) {
+                    int startRow = rowKey;
+                    int startCol = (colKey + range.getEndColumn() + 1) / 2;
+                    int endRow = range.getEndRow() + 1;
+                    int endCol = range.getEndColumn() + 1;
+                    XSSFClientAnchor anchor = new XSSFClientAnchor();
+                    anchor.setRow1(startRow);
+                    anchor.setCol1(startCol);
+                    anchor.setRow2(endRow);
+                    anchor.setCol2(endCol);
+                    XSSFSimpleShape shape = drawing.createSimpleShape(anchor);
+                    StyleTypeEnum bdStyle = StyleTypeEnum.getStyle(bd.getMl_tr().getS());
+                    if (ObjectUtil.isNotEmpty(bdStyle)) {
+                        shape.setShapeType(bdStyle.getBorderStyle().getCode());
+                    }
+                    String bdr = bd.getMl_tr().getCl().getRgb();
+                    if (ObjectUtil.isNotEmpty(bdr)) {
+                        XSSFColor color = color(bdr);
+                        if (color != null) {
+                            shape.setLineStyleColor(color.getRGB()[0], color.getRGB()[1], color.getRGB()[2]);
+                        }
+                    }
+                    shape.setShapeType(ShapeTypes.LINE_INV);
+                }
+            }
+        }
+    }
+
+    private static XSSFColor color(String rgbCole) {
+        rgbCole = rgbCole.replaceAll("\\s*", "").toUpperCase();
+        byte[] rgb = null;
+        try {
+            if (rgbCole.startsWith("#")) {
+                Color color = new Color(Integer.parseInt(rgbCole.substring(1), 16));
+                rgb = new byte[]{(byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue()};
+            } else if (rgbCole.startsWith("RGB(") && rgbCole.endsWith(")")) {
+                rgbCole = rgbCole.substring(4, rgbCole.length() - 1);
+                String[] rgbArray = rgbCole.split(",");
+                if (rgbArray.length >= 3) {
+                    int red = Integer.parseInt(rgbArray[0]);
+                    int green = Integer.parseInt(rgbArray[1]);
+                    int blue = Integer.parseInt(rgbArray[2]);
+                    rgb = new byte[]{(byte) red, (byte) green, (byte) blue};
+                }
+            } else if (rgbCole.startsWith("RGBA(") && rgbCole.endsWith(")")) {
+                rgbCole = rgbCole.substring(5, rgbCole.length() - 1);
+                String[] rgbArray = rgbCole.split(",");
+                if (rgbArray.length >= 3) {
+                    int red = Integer.parseInt(rgbArray[0]);
+                    int green = Integer.parseInt(rgbArray[1]);
+                    int blue = Integer.parseInt(rgbArray[2]);
+                    rgb = new byte[]{(byte) red, (byte) green, (byte) blue};
+                }
+            }
+        } catch (Exception e) {
+
+        }
+        XSSFColor xssfColor = rgb == null ? null : new XSSFColor(rgb);
+        return xssfColor;
+    }
+
+    /**
+     * 图片
+     */
+    private static void drawing(String sheetOrder, List<UniverResource> resources, List<UniverDrawing> drawingList, XSSFDrawing drawing, XSSFWorkbook workbook) {
+        UniverResource univerResource = resources.stream().filter(t -> ResourceEnum.SHEET_DRAWING_PLUGIN.name().equals(t.getName())).findFirst().orElse(null);
+        Map<String, UniverResourceData> drawingMap = new HashMap<>();
+        if (ObjectUtil.isNotEmpty(univerResource) && ObjectUtil.isNotEmpty(univerResource.getData())) {
+            Map<String, Object> data = JsonUtil.stringToMap(univerResource.getData());
+            data.forEach((key, value) -> {
+                drawingMap.put(key, JsonUtil.getJsonToBean(value, UniverResourceData.class));
+            });
+        }
+        UniverResourceData resourceData = drawingMap.get(sheetOrder);
+        if (ObjectUtil.isNotEmpty(resourceData)) {
+            List<String> orderList = resourceData.getOrder();
+            Map<String, UniverDrawing> data = resourceData.getData();
+            for (String order : orderList) {
+                UniverDrawing univerDrawing = data.get(order);
+                if (univerDrawing != null) {
+                    drawingList.add(univerDrawing);
+                }
+            }
+        }
+        //导出图片
+        for (UniverDrawing univerDrawing : drawingList) {
+            try {
+                String source = univerDrawing.getSource();
+                String imageType = univerDrawing.getImageSourceType();
+                byte[] bytes = null;
+                if (Objects.equals(ImageEnum.BASE64.name(), imageType)) {
+                    String regex = "data:image/\\w+;base64,";
+                    String base64Img = source;
+                    Pattern pattern = Pattern.compile(regex);
+                    Matcher matcher = pattern.matcher(source);
+                    if (matcher.find()) {
+                        base64Img = source.replace(matcher.group(), "");
+                    }
+                    bytes = Base64.decode(base64Img);
+                } else {
+                    if (source.startsWith(RequestType.HTTP)) {
+                        HttpRequest request = HttpRequest.of(source).method(Method.GET);
+                        bytes = request.execute().bodyBytes();
+                    } else {
+                        String[] split = source.split("=");
+                        String fileNameAll = DesUtil.aesDecode(split[split.length - 1]);
+                        String[] fileData = fileNameAll.split("#");
+                        String fileName = fileData.length > 1 ? fileData[1] : "";
+                        String type = fileData.length > 2 ? fileData[2] : "";
+                        String typePath = FilePathUtil.getFilePath(type.toLowerCase());
+                        bytes = FileUploadUtils.downloadFile(new FileParameter(typePath, fileName));
+                    }
+                }
+                if (bytes != null && bytes.length > 0) {
+                    UniverTransform sheetTransform = univerDrawing.getSheetTransform();
+                    UniverOffset from = sheetTransform.getFrom();
+                    UniverOffset to = sheetTransform.getTo();
+                    //图片导出
+                    XSSFClientAnchor anchor = new XSSFClientAnchor();
+                    if (from.getColumn().equals(to.getColumn())) {
+                        to.setColumn(from.getColumn() + 5);
+                    }
+                    anchor.setRow1(from.getRow());
+                    anchor.setCol1(from.getColumn());
+                    anchor.setRow2(to.getRow());
+                    anchor.setCol2(to.getColumn());
+                    anchor.setAnchorType(ClientAnchor.AnchorType.DONT_MOVE_DO_RESIZE);
+                    int imageIndex = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG);
+                    drawing.createPicture(anchor, imageIndex);
+                }
+            } catch (Exception e) {
+                log.error("图片导出失败:{}", e.getMessage());
+            }
+        }
+    }
+
+    /**
+     * 条件格式
+     */
+    private static void format(String sheetOrder, List<UniverResource> resources, XSSFSheet sheet) {
+        StylesTable styles = sheet.getWorkbook().getStylesSource();
+        UniverResource univerResource = resources.stream().filter(t -> ResourceEnum.SHEET_CONDITIONAL_FORMATTING_PLUGIN.name().equals(t.getName())).findFirst().orElse(null);
+        Map<String, List<UniverResourceData>> foramtMap = new HashMap<>();
+        if (ObjectUtil.isNotEmpty(univerResource) && ObjectUtil.isNotEmpty(univerResource.getData())) {
+            Map<String, Object> data = JsonUtil.stringToMap(univerResource.getData());
+            data.forEach((key, value) -> {
+                foramtMap.put(key, JsonUtil.getJsonToList(value, UniverResourceData.class));
+            });
+        }
+        List<UniverResourceData> data = foramtMap.get(sheetOrder) != null ? foramtMap.get(sheetOrder) : new ArrayList<>();
+        CTWorksheet ctWorksheet = sheet.getCTWorksheet();
+        List<CTConditionalFormatting> conditionalList = new ArrayList<>();
+        for (UniverResourceData resourceData : data) {
+            UniverRule rule = resourceData.getRule();
+            Boolean stopIfTrue = resourceData.getStopIfTrue();
+            List<UniverSheetRange> ranges = resourceData.getRanges();
+            if (ObjectUtil.isNotEmpty(rule)) {
+                List<CTCfRule> ruleList = new ArrayList<>();
+                List<UniverConfig> configList = new ArrayList<>();
+                Object ruleConfig = rule.getConfig();
+                if (ObjectUtil.isNotEmpty(ruleConfig)) {
+                    if (ruleConfig instanceof List) {
+                        configList.addAll(JsonUtil.getJsonToList(ruleConfig, UniverConfig.class));
+                    } else if (ruleConfig instanceof Map) {
+                        configList.add(JsonUtil.getJsonToBean(ruleConfig, UniverConfig.class));
+                    }
+                }
+                List<String> regions = new ArrayList<>();
+                for (UniverSheetRange range : ranges) {
+                    regions.add(new CellRangeAddress(range.getStartRow(), range.getEndRow(), range.getStartColumn(), range.getEndColumn()).formatAsString());
+                }
+                String type = rule.getType();
+                String subType = rule.getSubType();
+                Boolean showValue = rule.getIsShowValue();
+                String operator = rule.getOperator();
+                FormatTypeEnum formatTypeEnum = FormatTypeEnum.getFormat(type);
+                CTCfRule cfRule = CTCfRule.Factory.newInstance();
+                cfRule.setStopIfTrue(stopIfTrue);
+                STCfType.Enum typeEnum = STCfType.Enum.forString(type);
+                cfRule.setType(typeEnum);
+                switch (formatTypeEnum) {
+                    case colorScale:
+                        CTColorScale scale = cfRule.addNewColorScale();
+                        for (UniverConfig univerConfig : configList) {
+                            UniverValue univerValue = univerConfig.getValue();
+                            if (univerValue == null) {
+                                continue;
+                            }
+                            String valueType = univerValue.getType();
+                            String value = univerValue.getValue() != null ? univerValue.getValue().toString() : "";
+                            if (Objects.equals(SubTypeEnum.expression.getCode(), valueType)) {
+                                value = value.replace("=", "");
+                            }
+                            CTCfvo ctCfvo = scale.addNewCfvo();
+                            ctCfvo.setType(STCfvoType.Enum.forString(valueType));
+                            ctCfvo.setVal(value);
+                            XSSFColor color = color(univerConfig.getColor());
+                            if (color != null) {
+                                CTColor ctColor = scale.addNewColor();
+                                ctColor.setRgb(color.getRGB());
+                            }
+                        }
+                        ruleList.add(cfRule);
+                        break;
+                    case iconSet:
+                        CTIconSet icons = cfRule.addNewIconSet();
+                        icons.setShowValue(showValue);
+                        for (int i = configList.size() - 1; i >= 0; i--) {
+                            UniverConfig univerConfig = configList.get(i);
+                            UniverValue value = univerConfig.getValue();
+                            if (value == null) {
+                                continue;
+                            }
+                            String iconType = value.getType();
+                            String icon = univerConfig.getIconType();
+                            String valueOperator = univerConfig.getOperator();
+                            String iconValue = value.getValue() != null ? value.getValue().toString() : "";
+                            if (Objects.equals(SubTypeEnum.expression.getCode(), iconType)) {
+                                iconValue = iconValue.replace("=", "");
+                            }
+                            CTCfvo ctCfvo = icons.addNewCfvo();
+                            ctCfvo.setVal(iconValue);
+                            ctCfvo.setGte(Objects.equals(valueOperator, OperatorEnum.greaterThanOrEqual.name()));
+                            ctCfvo.setType(STCfvoType.Enum.forString(iconType));
+                            icons.setIconSet(STIconSetType.Enum.forString(icon));
+                        }
+                        boolean reverse = configList.size() > 0 && !Objects.equals(configList.get(0).getIconId(), "0");
+                        icons.setReverse(reverse);
+                        ruleList.add(cfRule);
+                        break;
+                    case dataBar:
+                        CTDataBar bar = cfRule.addNewDataBar();
+                        bar.setShowValue(showValue);
+                        for (UniverConfig config : configList) {
+                            UniverValue min = config.getMin();
+                            UniverValue max = config.getMax();
+                            if (min != null && max != null) {
+                                String minType = min.getType();
+                                String minValue = min.getValue() != null ? min.getValue().toString() : "";
+                                if (Objects.equals(SubTypeEnum.expression.getCode(), minType)) {
+                                    minValue = minValue.replace("=", "");
+                                }
+                                String maxType = max.getType();
+                                String maxValue = max.getValue() != null ? max.getValue().toString() : "";
+                                if (Objects.equals(SubTypeEnum.expression.getCode(), maxType)) {
+                                    maxValue = maxValue.replace("=", "");
+                                }
+                                List<String> dataBarType = ImmutableList.of(OperatorEnum.min.name(), OperatorEnum.max.name());
+                                for (int i = 0; i < dataBarType.size(); i++) {
+                                    String barType = i == 0 ? minType : maxType;
+                                    String barValue = i == 0 ? minValue : maxValue;
+                                    CTCfvo ctCfvo = bar.addNewCfvo();
+                                    ctCfvo.setType(STCfvoType.Enum.forString(barType));
+                                    ctCfvo.setVal(barValue);
+
+                                    XSSFColor positiveColor = color(config.getPositiveColor());
+                                    if (positiveColor != null) {
+                                        CTColor ctColor = bar.addNewColor();
+                                        ctColor.setRgb(positiveColor.getRGB());
+                                    }
+
+                                    XSSFColor nativeColor = color(config.getNativeColor());
+                                    if (nativeColor == null) {
+                                        CTColor ctColor = bar.addNewColor();
+                                        ctColor.setRgb(nativeColor.getRGB());
+                                    }
+                                }
+                            }
+                        }
+                        ruleList.add(cfRule);
+                        break;
+                    default:
+                        List<String> cell = ImmutableList.of(SubTypeEnum.cellIs.getCode(), SubTypeEnum.equal.getCode(), SubTypeEnum.notEqual.getCode());
+                        boolean isNumber = cell.contains(subType) || cell.contains(operator);
+                        //平均值
+                        boolean isAverage = Objects.equals(SubTypeEnum.aboveAverage.getCode(), subType);
+                        //TOP
+                        boolean isRank = Objects.equals(SubTypeEnum.top10.getCode(), subType);
+                        //公式
+                        boolean isFormula = Objects.equals(SubTypeEnum.expression.getCode(), subType);
+                        //日期
+                        boolean isTime = Objects.equals(SubTypeEnum.timePeriod.getCode(), subType);
+                        String ruleType = operator;
+                        if (isNumber) {
+                            ruleType = SubTypeEnum.cellIs.getType();
+                        } else if (isAverage) {
+                            ruleType = SubTypeEnum.aboveAverage.getType();
+                        } else if (isRank) {
+                            ruleType = SubTypeEnum.top10.getType();
+                        } else if (isFormula) {
+                            ruleType = SubTypeEnum.expression.getType();
+                        } else if (isTime) {
+                            ruleType = SubTypeEnum.timePeriod.getType();
+                        }
+                        if (StringUtil.isEmpty(ruleType)) {
+                            ruleType = subType;
+                        }
+                        Object value = rule.getValue();
+                        String data1 = null;
+                        String data2 = null;
+                        String text = null;
+                        Long rank = null;
+                        Boolean bottom = null;
+                        Boolean percent = null;
+                        if (value != null) {
+                            if (isNumber) {
+                                if (value instanceof List) {
+                                    List<Object> valueList = (List<Object>) value;
+                                    for (int i = 0; i < valueList.size(); i++) {
+                                        Object numberValu = valueList.get(i);
+                                        if (numberValu != null) {
+                                            if (i == 0) {
+                                                data1 = valueList.get(i).toString();
+                                            } else {
+                                                data2 = valueList.get(i).toString();
+                                            }
+                                        }
+                                    }
+                                } else {
+                                    data1 = value.toString();
+                                }
+                            } else if (isRank) {
+                                rank = Long.valueOf(value.toString());
+                                bottom = rule.getIsBottom();
+                                percent = rule.getIsPercent();
+                            } else if (isFormula) {
+                                data1 = value.toString().replace("=", "");
+                            } else {
+                                text = value.toString();
+                            }
+                        }
+                        cfRule.setType(STCfType.Enum.forString(ruleType));
+                        if (data1 != null) {
+                            cfRule.addFormula(data1);
+                        }
+                        if (data2 != null) {
+                            cfRule.addFormula(data2);
+                        }
+                        if (operator != null) {
+                            STConditionalFormattingOperator.Enum anOperator = STConditionalFormattingOperator.Enum.forString(operator);
+                            if (anOperator != null) {
+                                cfRule.setOperator(anOperator);
+                            }
+                            STTimePeriod.Enum timePeriod = STTimePeriod.Enum.forString(operator);
+                            if (timePeriod != null) {
+                                cfRule.setTimePeriod(timePeriod);
+                            }
+                        }
+                        if (text != null) {
+                            cfRule.setText(text);
+                        }
+                        if (rank != null) {
+                            cfRule.setRank(rank);
+                        }
+                        if (bottom != null) {
+                            cfRule.setBottom(bottom);
+                        }
+                        if (percent != null) {
+                            cfRule.setPercent(percent);
+                        }
+                        if (isAverage) {
+                            cfRule.setAboveAverage(Objects.equals(OperatorEnum.greaterThan.name(), operator));
+                        }
+                        UniverStyle style = rule.getStyle();
+                        if (style != null) {
+                            CTDxf ctDxf = CTDxf.Factory.newInstance();
+                            XSSFColor bgColor = color(style.getBg().getRgb() != null ? style.getBg().getRgb() : "");
+                            if (bgColor != null) {
+                                CTFill ctFill = CTFill.Factory.newInstance();
+                                CTPatternFill patternFill = CTPatternFill.Factory.newInstance();
+                                patternFill.setBgColor(bgColor.getCTColor());
+                                ctFill.setPatternFill(patternFill);
+                                ctDxf.setFill(ctFill);
+                            }
+
+                            CTFont ctFont = CTFont.Factory.newInstance();
+                            XSSFColor fontColor = color(style.getCl().getRgb() != null ? style.getCl().getRgb() : "");
+                            if (fontColor != null) {
+                                CTColor ctColor = fontColor.getCTColor();
+                                ctFont.setColorArray(new CTColor[]{ctColor});
+                            }
+                            CTUnderlineProperty underline = CTUnderlineProperty.Factory.newInstance();
+                            underline.setVal(style.getUl() != null && Objects.equals(style.getUl().getS(), 1) ? STUnderlineValues.SINGLE : STUnderlineValues.NONE);
+                            ctFont.setUArray(new CTUnderlineProperty[]{underline});
+
+                            CTBooleanProperty italic = CTBooleanProperty.Factory.newInstance();
+                            italic.setVal(Objects.equals(style.getIt(), 1));
+                            ctFont.setIArray(new CTBooleanProperty[]{italic});
+
+                            CTBooleanProperty bold = CTBooleanProperty.Factory.newInstance();
+                            bold.setVal(Objects.equals(style.getBl(), 1));
+                            ctFont.setBArray(new CTBooleanProperty[]{bold});
+
+                            UniverStyleTextDecoration st = style.getSt();
+                            CTBooleanProperty strike = CTBooleanProperty.Factory.newInstance();
+                            strike.setVal(st != null && Objects.equals(st.getS(), 1));
+                            ctFont.setStrikeArray(new CTBooleanProperty[]{strike});
+                            ctDxf.setFont(ctFont);
+                            int dxfId = styles.putDxf(ctDxf);
+                            cfRule.setDxfId(dxfId - 1);
+                        }
+                        ruleList.add(cfRule);
+                        break;
+                }
+                CTConditionalFormatting conditionalFormatting = ctWorksheet.addNewConditionalFormatting();
+                conditionalFormatting.setCfRuleArray(ruleList.toArray(new CTCfRule[ruleList.size()]));
+                conditionalFormatting.setSqref(regions);
+                conditionalList.add(conditionalFormatting);
+            }
+        }
+        ctWorksheet.setConditionalFormattingArray(conditionalList.toArray(new CTConditionalFormatting[conditionalList.size()]));
+    }
+
+    /**
+     * 数据有效性
+     */
+    private static void dataValidation(String sheetOrder, List<UniverResource> resources, XSSFSheet sheet) {
+        UniverResource univerResource = resources.stream().filter(t -> ResourceEnum.SHEET_DATA_VALIDATION_PLUGIN.name().equals(t.getName())).findFirst().orElse(null);
+        Map<String, List<UniverResourceData>> dataValidationMap = new HashMap<>();
+        if (ObjectUtil.isNotEmpty(univerResource) && ObjectUtil.isNotEmpty(univerResource.getData())) {
+            Map<String, Object> data = JsonUtil.stringToMap(univerResource.getData());
+            data.forEach((key, value) -> {
+                dataValidationMap.put(key, JsonUtil.getJsonToList(value, UniverResourceData.class));
+            });
+        }
+        XSSFDataValidationHelper dataValidation = new XSSFDataValidationHelper(sheet);
+        List<UniverResourceData> data = dataValidationMap.get(sheetOrder) != null ? dataValidationMap.get(sheetOrder) : new ArrayList<>();
+        for (UniverResourceData resourceData : data) {
+            CellRangeAddressList addressList = new CellRangeAddressList();
+            for (UniverSheetRange range : resourceData.getRanges()) {
+                addressList.addCellRangeAddress(new CellRangeAddress(range.getStartRow(), range.getEndRow(), range.getStartColumn(), range.getEndColumn()));
+            }
+            String formula1 = resourceData.getFormula1() != null ? resourceData.getFormula1() : "";
+            String formula2 = resourceData.getFormula2() != null ? resourceData.getFormula2() : "";
+            ValidationType validationType = ValidationType.getValidationType(resourceData.getType());
+            String value1 = Objects.equals(validationType, ValidationType.checkbox) ? formula1 + "," + formula2 : formula1;
+            String value2 = formula2;
+            operatorTypeEnum operator = operatorTypeEnum.getOperator(resourceData.getOperator());
+            XSSFDataValidationConstraint constraint = new XSSFDataValidationConstraint(validationType.getValidationType(), operator.getOperator(), value1, value2);
+            constraint.setExplicitListValues(value1.split(","));
+            DataValidation validation = dataValidation.createValidation(constraint, addressList);
+            validation.setErrorStyle(resourceData.getErrorStyle() != null ? 0 : 1);
+            validation.setEmptyCellAllowed(resourceData.getAllowBlank() != null ? resourceData.getAllowBlank() : true);
+            if (resourceData.getError() != null) {
+                validation.createErrorBox(resourceData.getError(), "");
+            }
+            if (resourceData.getRenderMode() != null) {
+                validation.setSuppressDropDownArrow(!Objects.equals(resourceData.getRenderMode(), 0));
+            }
+            validation.setShowErrorBox(resourceData.getShowErrorMessage() != null ? resourceData.getShowErrorMessage() : false);
+            sheet.addValidationData(validation);
+        }
+    }
+
+    /**
+     * 筛选
+     */
+    private static void filter(String sheetOrder, List<UniverResource> resources, XSSFSheet sheet) {
+        UniverResource univerResource = resources.stream().filter(t -> ResourceEnum.SHEET_FILTER_PLUGIN.name().equals(t.getName())).findFirst().orElse(null);
+        Map<String, UniverResourceData> filterMap = new HashMap<>();
+        if (ObjectUtil.isNotEmpty(univerResource) && ObjectUtil.isNotEmpty(univerResource.getData())) {
+            Map<String, Object> data = JsonUtil.stringToMap(univerResource.getData());
+            data.forEach((key, value) -> {
+                filterMap.put(key, JsonUtil.getJsonToBean(value, UniverResourceData.class));
+            });
+        }
+        UniverResourceData data = filterMap.get(sheetOrder) != null ? filterMap.get(sheetOrder) : new UniverResourceData();
+        UniverSheetRange ref = data.getRef();
+        if (ref != null) {
+            sheet.setAutoFilter(new CellRangeAddress(ref.getStartRow(), ref.getEndRow(), ref.getStartColumn(), ref.getEndColumn()));
+            List<CTFilterColumn> filterColumns = new ArrayList<>();
+            CTAutoFilter autoFilter = sheet.getCTWorksheet().getAutoFilter();
+            for (UniverFilters filters : data.getFilterColumns()) {
+                Long colId = filters.getColId();
+                UniverCustomFilters customFilters = filters.getFilters();
+                //poi方法
+                CTFilterColumn column = autoFilter.addNewFilterColumn();
+                column.setColId(colId);
+                CTCustomFilters ctCustomFilters = column.addNewCustomFilters();
+                if (null != filters.getCustomFilters()) {
+                    customFilters = filters.getCustomFilters();
+                    for (UniverCustomFilters customFilter : customFilters.getCustomFilters()) {
+                        CTCustomFilter ctCustomFilter = ctCustomFilters.addNewCustomFilter();
+                        String val = customFilter.getVal();
+                        if (val != null) {
+                            ctCustomFilter.setVal(val);
+                        }
+                        String operator = customFilter.getOperator();
+                        if (operator != null) {
+                            ctCustomFilter.setOperator(STFilterOperator.Enum.forString(operator));
+                        }
+                        List<String> stringList = customFilter.getFilters();
+                        if (CollectionUtil.isNotEmpty(stringList)) {
+                            for (String string : stringList) {
+                                CTCustomFilter addNewCustomFilter = ctCustomFilters.addNewCustomFilter();
+                                addNewCustomFilter.setVal(string);
+                                if (operator != null) {
+                                    addNewCustomFilter.setOperator(STFilterOperator.Enum.forString(operator));
+                                }
+                            }
+                        }
+                        List<UniverCustomFilters> customFiltersList = customFilters.getCustomFilters();
+                        if (CollectionUtil.isNotEmpty(customFiltersList)) {
+                            for (UniverCustomFilters univerCustomFilters : customFiltersList) {
+                                CTCustomFilter addNewCustomFilter = ctCustomFilters.addNewCustomFilter();
+                                if (null != univerCustomFilters.getVal()) {
+                                    addNewCustomFilter.setVal(univerCustomFilters.getVal());
+                                }
+                                if (operator != null) {
+                                    addNewCustomFilter.setOperator(STFilterOperator.Enum.forString(operator));
+                                }
+                                if (null != univerCustomFilters.getOperator()) {
+                                    addNewCustomFilter.setOperator(STFilterOperator.Enum.forString(univerCustomFilters.getOperator()));
+                                }
+                            }
+                        }
+                    }
+
+                } else {
+                    for (String customFilter : customFilters.getFilters()) {
+                        String val = customFilters.getVal();
+                        String operator = customFilters.getOperator();
+                        CTCustomFilter addNewCustomFilter = ctCustomFilters.addNewCustomFilter();
+                        addNewCustomFilter.setVal(customFilter);
+                        if (operator != null) {
+                            addNewCustomFilter.setOperator(STFilterOperator.Enum.forString(operator));
+                        }
+                    }
+                }
+                if (BeanUtil.isNotEmpty(customFilters) && null != customFilters.getAnd()) {
+                    ctCustomFilters.setAnd(Objects.equals(customFilters.getAnd(), 1));
+                }
+
+                filterColumns.add(column);
+
+            }
+            //筛选隐藏
+            List<Integer> cachedFilteredOut = data.getCachedFilteredOut();
+            for (Integer rowIndex : cachedFilteredOut) {
+                XSSFRow row = sheet.getRow(rowIndex);
+                row.setZeroHeight(true);
+            }
+            autoFilter.setFilterColumnArray(filterColumns.toArray(new CTFilterColumn[filterColumns.size()]));
+        }
+    }
+
+    /**
+     * 名称管理器
+     */
+    private static void definedName(List<UniverResource> resources, Map<String, UniverSheet> sheetMap, Map<XSSFCell, String> linkMap, XSSFWorkbook workbook) {
+        UniverResource univerResource = resources.stream().filter(t -> ResourceEnum.SHEET_DEFINED_NAME_PLUGIN.name().equals(t.getName())).findFirst().orElse(null);
+        Map<String, UniverResourceData> definedNameMap = new HashMap<>();
+        if (ObjectUtil.isNotEmpty(univerResource) && ObjectUtil.isNotEmpty(univerResource.getData())) {
+            Map<String, Object> data = JsonUtil.stringToMap(univerResource.getData());
+            data.forEach((key, value) -> {
+                definedNameMap.put(key, JsonUtil.getJsonToBean(value, UniverResourceData.class));
+            });
+        }
+        Map<String, Integer> sheetName = new HashMap<>();
+        for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
+            XSSFSheet sheet = workbook.getSheetAt(i);
+            sheetName.put(sheet.getSheetName(), i);
+        }
+        definedNameMap.forEach((key, value) -> {
+            String localSheetId = value.getLocalSheetId();
+            Integer sheetIndex = -1;
+            if (!Objects.equals("AllDefaultWorkbook", localSheetId)) {
+                UniverSheet univerSheet = sheetMap.get(localSheetId);
+                sheetIndex = sheetName.get(univerSheet.getName());
+            }
+            if (sheetIndex != null) {
+                XSSFName name = workbook.createName();
+                name.setSheetIndex(sheetIndex);
+                String formulaValue = value.getFormulaOrRefString();
+                name.setNameName(value.getName());
+                name.setRefersToFormula(formulaValue.startsWith("=") ? formulaValue.substring(1) : formulaValue);
+                name.setComment(value.getComment());
+            }
+        });
+
+        linkMap.forEach((key, value) -> {
+            XSSFCreationHelper createHelper = workbook.getCreationHelper();
+            String gid = "#gid=";
+            String rangeId = "#rangeid=";
+            boolean isGid = value.startsWith(gid);
+            boolean isRangeId = value.startsWith(rangeId);
+            XSSFHyperlink link = createHelper.createHyperlink(!isGid && !isRangeId ? HyperlinkType.URL : HyperlinkType.DOCUMENT);
+            if (isGid) {
+                value = value.replace(gid, "");
+                String[] split = value.split("&range=");
+                String sheetId = split[0];
+                String cellName = split.length > 1 ? split[1] : "A1";
+                UniverSheet univerSheet = sheetMap.get(sheetId);
+                if (univerSheet != null) {
+                    link.setAddress(univerSheet.getName() + "!" + cellName);
+                }
+            } else if (isRangeId) {
+                value = value.replace(rangeId, "");
+                UniverResourceData definedName = definedNameMap.get(value);
+                if (definedName != null) {
+                    String name = definedName.getName();
+                    link.setAddress(name);
+                }
+            } else {
+                link.setAddress(value);
+            }
+            Font hyperlinkFont = workbook.createFont();
+//            XSSFCellStyle cellStyle = key.getCellStyle();
+            XSSFCellStyle cellStyle = workbook.createCellStyle();
+            hyperlinkFont.setUnderline(Font.U_SINGLE);
+            hyperlinkFont.setColor(IndexedColors.BLUE.getIndex());
+            cellStyle.setFont(hyperlinkFont);
+            key.setCellStyle(cellStyle);
+            key.setHyperlink(link);
+        });
+    }
+
+}

+ 154 - 0
jnpf-datareport-univer-common/src/main/java/jnpf/util/ZxingUtil.java

@@ -0,0 +1,154 @@
+package jnpf.util;
+
+import cn.hutool.core.img.ImgUtil;
+import com.google.common.collect.ImmutableList;
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.EncodeHintType;
+import com.google.zxing.MultiFormatWriter;
+import com.google.zxing.common.BitMatrix;
+import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
+import jnpf.enums.ZxingEnum;
+import jnpf.univer.sheet.*;
+import jnpf.univer.zxing.UniverZxingModel;
+import lombok.extern.slf4j.Slf4j;
+
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.util.List;
+import java.util.*;
+
+@Slf4j
+public class ZxingUtil {
+
+    public static UniverZxingModel zxingImage(Map<Integer, UniverSheetRowData> sheetRowData, Map<Integer, UniverSheetColumnData> sheetColumnData, UniverSheet sheet, UniverSheetRange range, String displayType) {
+        UniverZxingModel zxingModel = new UniverZxingModel();
+        if (range != null) {
+            List<Integer> heightList = new ArrayList<>();
+            heightList.add(0);
+            Integer startRow = range.getStartRow();
+            Integer endRow = range.getEndRow();
+            for (int i = startRow; i <= endRow; i++) {
+                UniverSheetRowData rowData = sheetRowData.get(i);
+                heightList.add(rowData != null ? rowData.getH() != null ? rowData.getH() : rowData.getAh() != null ? rowData.getAh() : sheet.getDefaultRowHeight() : sheet.getDefaultRowHeight());
+            }
+            List<Integer> widthList = new ArrayList<>();
+            widthList.add(0);
+            Integer startColumn = range.getStartColumn();
+            Integer endColumn = range.getEndColumn();
+            for (int i = startColumn; i <= endColumn; i++) {
+                UniverSheetColumnData columnData = sheetColumnData.get(i);
+                widthList.add(columnData != null && columnData.getW() != null ? columnData.getW() : sheet.getDefaultColumnWidth());
+            }
+            int heightSum = heightList.stream().mapToInt(Integer::intValue).sum();
+            int widthSum = widthList.stream().mapToInt(Integer::intValue).sum();
+            if (Objects.equals(ZxingEnum.QRCODE.getType(), displayType)) {
+                int min = Collections.min(ImmutableList.of(widthSum, heightSum));
+                zxingModel.setHeight(min * 5);
+                zxingModel.setWidth(min * 5);
+                zxingModel.setUniverHeight(min - 2);
+                zxingModel.setUniverWidth(min - 2);
+            } else {
+                zxingModel.setHeight(heightSum / 2);
+                zxingModel.setWidth(widthSum * 2);
+                zxingModel.setWidth(200 - 10);
+                zxingModel.setHeight(50);
+
+                zxingModel.setUniverHeight(heightSum - 2);
+                zxingModel.setUniverWidth(widthSum - 2);
+            }
+        }
+        return zxingModel;
+    }
+
+    public static String zxing(UniverZxingModel zxingModel) {
+        String base64 = "";
+        ZxingEnum zxingEnum = ZxingEnum.getType(zxingModel.getDisplayType());
+        BarcodeFormat format = BarcodeFormat.QR_CODE;
+        switch (zxingEnum) {
+            case QRCODE:
+            case BARCODE:
+                if (StringUtil.isNotEmpty(zxingModel.getFormat())) {
+                    ZxingEnum type = ZxingEnum.getType(zxingModel.getFormat());
+                    List<ZxingEnum> typeList = ImmutableList.of(ZxingEnum.ITF, ZxingEnum.EAN8, ZxingEnum.EAN13, ZxingEnum.BARCODE,
+                            ZxingEnum.CODABAR, ZxingEnum.CODE128, ZxingEnum.CODE39);
+                    if (typeList.contains(type)) {
+                        format = BarcodeFormat.valueOf(type.getValue());
+                    }
+                }
+                base64 = base64Image(format, zxingModel);
+                break;
+        }
+        return base64;
+    }
+
+    private static String base64Image(BarcodeFormat format, UniverZxingModel zxingValue) {
+        String baset64 = "";
+        try {
+            String value = zxingValue.getText();
+            int height = zxingValue.getHeight();
+            int width = zxingValue.getWidth();
+            String level = zxingValue.getErrorCorrectionLevel();
+            // 编码内容, 编码类型, 宽度, 高度, 设置参数
+            Map<EncodeHintType, Object> hints = new Hashtable<>();
+            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
+            // 设置容错等级
+            if (StringUtil.isNotEmpty(level)) {
+                hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.valueOf(level));
+            }
+            hints.put(EncodeHintType.MARGIN, 1);
+            BitMatrix matrix = new MultiFormatWriter().encode(value, format, width, height, hints);
+
+            // 动态计算增加的高度用于备注文本
+            int textHeight = 5;
+            String backgroundColor = zxingValue.getBackground();
+            int background = rgb(backgroundColor, new Color(244, 245, 246).getRGB());
+            String foregroundColor = zxingValue.getLineColor();
+            int foreground = rgb(foregroundColor, new Color(0, 0, 0).getRGB());
+            // 创建带有二维码和备注文本的
+            BufferedImage image = new BufferedImage(width + textHeight, height + textHeight, BufferedImage.TYPE_INT_RGB);
+            Graphics2D g = image.createGraphics();
+            g.setColor(new Color(background));
+            g.fillRect(0, 0, width + textHeight, height + textHeight);
+
+            // 绘制二维码到 BufferedImage
+            for (int x = 0; x < width; x++) {
+                for (int y = 0; y < height; y++) {
+                    image.setRGB(x + 3, y + 3, matrix.get(x, y) ? foreground : background);
+                }
+            }
+            baset64 = "data:image/jpeg;base64," + ImgUtil.toBase64(image, "jpeg");
+        } catch (Exception e) {
+            log.error(e.getMessage());
+        }
+        return baset64;
+    }
+
+    private static int rgb(String rgbCole, int imageColor) {
+        Color color = null;
+        try {
+            color = new Color(Integer.parseInt(rgbCole.substring(1), 16));
+        } catch (Exception e) {
+        }
+        return color == null ? imageColor : color.getRGB();
+    }
+
+    // 底部添加文本
+    private static void addText(BufferedImage image, String text, int width, int height, int textHeight, int colorRgb) {
+        Graphics2D g2 = image.createGraphics();
+        g2.setColor(new Color(colorRgb));
+        g2.setFont(new Font("Arial", Font.PLAIN, 20));  // 设置字体
+
+        // 获取文本的宽度以便居中对齐
+        FontMetrics fm = g2.getFontMetrics();
+        int textWidth = fm.stringWidth(text);
+        int x = (width - textWidth) / 2;
+
+        // 调整 y 坐标位置,将文本稍微上移
+        int padding = 5;  // 增加一个 padding 值,让文本上移一点,避免贴得太近
+        int y = height + (textHeight - fm.getHeight()) / 2 + fm.getAscent() - padding;
+
+        // 绘制文本
+        g2.drawString(text, x, y);
+        g2.dispose(); // 释放资源
+    }
+}

+ 16 - 0
jnpf-datareport-univer-common/src/main/java/jnpf/util/excel/ExcelParser.java

@@ -0,0 +1,16 @@
+package jnpf.util.excel;
+
+import jnpf.univer.model.UniverWorkBook;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/9/30 下午3:10
+ */
+public abstract class ExcelParser {
+    public abstract UniverWorkBook formFile(InputStream inputStream) throws IOException;
+}

+ 346 - 0
jnpf-datareport-univer-common/src/main/java/jnpf/util/excel/ImportExcel.java

@@ -0,0 +1,346 @@
+package jnpf.util.excel;
+
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.json.JSONUtil;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.io.Files;
+import jnpf.constant.MsgCode;
+import jnpf.enums.CellDataTypeEnum;
+import jnpf.enums.ResourceEnum;
+import jnpf.exception.DataException;
+import jnpf.univer.model.UniverWorkBook;
+import jnpf.univer.properties.*;
+import jnpf.univer.resources.UniverResource;
+import jnpf.univer.resources.UniverResourceData;
+import jnpf.univer.sheet.*;
+import jnpf.univer.style.UniverStyle;
+import jnpf.util.StringUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.common.usermodel.HyperlinkType;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.PaneInformation;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+public class ImportExcel {
+
+    private static Map<String, ImportExcelParser> excelMap = ImmutableMap.of(
+            "xlsx", new ImportXssfExcel(),
+            "xls", new ImportHssfExcel()
+    );
+
+    public static UniverWorkBook formFile(MultipartFile file) throws IOException {
+        //todo 推荐使用xlsx方法
+        String fileName = file.getOriginalFilename();
+        String excelType = Files.getFileExtension(fileName);
+        ImportExcelParser excelParser = excelMap.get(excelType);
+        if (excelParser == null) {
+            throw new DataException(MsgCode.ETD110.get());
+        }
+        UniverWorkBook univerWorkBook = ImportExcel.univerWorkBook(file.getInputStream(), excelParser);
+        return univerWorkBook;
+    }
+
+    private static UniverWorkBook univerWorkBook(InputStream inputStream, ImportExcelParser excelParser) throws IOException {
+        Workbook workbook = WorkbookFactory.create(inputStream);
+        UniverWorkBook univerWorkBook = new UniverWorkBook();
+        String unitId = RandomUtil.randomString(10);
+        univerWorkBook.setId(unitId);
+        univerWorkBook.setName("");
+        Map<UniverStyle, String> styleMap = new HashMap<>();
+        List<UniverSheet> sheetList = new ArrayList<>();
+        //sheet名称对应的id
+        Map<String, String> univerSheetMap = new HashMap<>();
+        for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
+            String sheetId = RandomUtil.randomString(10);
+            Sheet sheet = workbook.getSheetAt(i);
+            univerSheetMap.put(sheet.getSheetName(), sheetId);
+        }
+        Map<String, String> definedName = new HashMap<>();
+        Map<String, UniverResourceData> definedNameMap = definedName(workbook, definedName, univerSheetMap);
+        for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
+            Sheet sheet = workbook.getSheetAt(i);
+            String sheetName = sheet.getSheetName();
+            String sheetId = univerSheetMap.get(sheetName);
+            UniverSheet univerSheet = new UniverSheet();
+            univerSheet.setId(sheetId);
+            univerSheet.setName(sheetName);
+            univerSheet.setHidden(!workbook.isSheetHidden(i) ? 0 : 1);
+            univerSheet.setTabColor("");
+            //冻结位置
+            UniverSheetFreeze sheetFreeze = new UniverSheetFreeze();
+            PaneInformation freeze = sheet.getPaneInformation();
+            if (freeze != null) {
+                int freezeColumn = freeze.getVerticalSplitLeftColumn();
+                if (freezeColumn > 0) {
+                    sheetFreeze.setStartColumn(freezeColumn);
+                    sheetFreeze.setXSplit(freezeColumn);
+                }
+                int freezeRow = freeze.getHorizontalSplitTopRow();
+                if (freezeRow > 0) {
+                    sheetFreeze.setStartRow(freezeRow);
+                    sheetFreeze.setYSplit(freezeRow);
+                }
+            }
+            univerSheet.setFreeze(sheetFreeze);
+
+            Map<Integer, UniverSheetRowData> rowData = new HashMap<>();
+            Map<Integer, UniverSheetColumnData> columnData = new HashMap<>();
+            Map<Integer, Map<Integer, UniverSheetCellData>> cellData = new HashMap<>();
+            for (int rowCount = 0; rowCount <= sheet.getLastRowNum(); rowCount++) {
+                Row row = sheet.getRow(rowCount);
+                Map<Integer, UniverSheetCellData> cells = new HashMap<>();
+                if (null != row) {
+                    for (int columnCount = 0; columnCount <= row.getLastCellNum(); columnCount++) {
+                        Cell cell = row.getCell(columnCount);
+                        UniverSheetCellData univerSheetCellData = new UniverSheetCellData();
+                        if (null != cell) {
+                            //数据
+                            Object value = null;
+                            String formula = null;
+                            CellType cellType = cell.getCellType();
+                            Integer type = null;
+                            switch (cellType) {
+                                case STRING:
+                                    value = cell.getStringCellValue();
+                                    type = CellDataTypeEnum.String.getCode();
+                                    break;
+                                case BOOLEAN:
+                                    value = cell.getBooleanCellValue();
+                                    type = CellDataTypeEnum.Boolean.getCode();
+                                    break;
+                                case NUMERIC:
+                                    value = new BigDecimal(cell.getNumericCellValue());
+                                    type = CellDataTypeEnum.Number.getCode();
+                                    break;
+                                case FORMULA:
+                                    formula = "=" + cell.getCellFormula();
+                                    type = CellDataTypeEnum.Formula.getCode();
+                                    break;
+                            }
+                            univerSheetCellData.setV(value);
+                            univerSheetCellData.setF(formula);
+                            univerSheetCellData.setT(type);
+                            //样式
+                            CellStyle cellStyle = cell.getCellStyle();
+                            UniverStyle style = excelParser.getUniverStyle(cellStyle, workbook);
+                            String styleName = styleMap.get(style) != null ? styleMap.get(style) : RandomUtil.randomString(6);
+                            styleMap.put(style, styleName);
+                            univerSheetCellData.setS(styleName);
+                            cells.put(columnCount, univerSheetCellData);
+                            UniverSheetColumnData univerSheetColumnData = new UniverSheetColumnData();
+                            univerSheetColumnData.setHd(!sheet.isColumnHidden(columnCount) ? 0 : 1);
+                            List<Integer> colHeight = new ArrayList<>();
+                            colHeight.add(100);
+                            colHeight.add((int) sheet.getColumnWidthInPixels(columnCount));
+                            univerSheetColumnData.setW(Collections.max(colHeight));
+                            columnData.put(columnCount, univerSheetColumnData);
+                            link(cell, value, definedName, univerSheetMap, univerSheetCellData);
+                        }
+                    }
+                    cellData.put(rowCount, cells);
+                    UniverSheetRowData univerSheetRowData = new UniverSheetRowData();
+                    univerSheetRowData.setHd(!row.getZeroHeight() ? 0 : 1);
+                    List<Integer> rowHeight = new ArrayList<>();
+                    rowHeight.add(50);
+                    rowHeight.add((int) row.getHeightInPoints());
+                    univerSheetRowData.setH(Collections.max(rowHeight));
+                    univerSheetRowData.setIa(0);
+                    rowData.put(rowCount, univerSheetRowData);
+                }
+            }
+            univerSheet.setCellData(cellData);
+            univerSheet.setRowData(rowData);
+            univerSheet.setColumnData(columnData);
+
+            List<UniverSheetRange> mergeData = new ArrayList<>();
+            for (CellRangeAddress region : sheet.getMergedRegions()) {
+                UniverSheetRange univerSheetRange = new UniverSheetRange();
+                univerSheetRange.setStartRow(region.getFirstRow());
+                univerSheetRange.setStartColumn(region.getFirstColumn());
+                univerSheetRange.setEndRow(region.getLastRow());
+                univerSheetRange.setEndColumn(region.getLastColumn());
+                mergeData.add(univerSheetRange);
+            }
+            univerSheet.setMergeData(mergeData);
+
+            UniverSheetRowHeader univerSheetRowHeader = new UniverSheetRowHeader();
+            univerSheetRowHeader.setHidden(0);
+            univerSheetRowHeader.setWidth(46);
+            univerSheet.setRowHeader(univerSheetRowHeader);
+
+            UniverSheetColumnHeader univerSheetColumnHeader = new UniverSheetColumnHeader();
+            univerSheetColumnHeader.setHidden(0);
+            univerSheetColumnHeader.setHeight(20);
+            univerSheet.setColumnHeader(univerSheetColumnHeader);
+
+            univerSheet.setZoomRatio(1);
+            univerSheet.setScrollTop(0);
+            univerSheet.setScrollLeft(0);
+            univerSheet.setDefaultColumnWidth(88);
+            univerSheet.setDefaultRowHeight(24);
+            List<Integer> rowCount = new ArrayList<>();
+            rowCount.add(100);
+            rowCount.add(rowData.size());
+            univerSheet.setRowCount(Collections.max(rowCount));
+            List<Integer> columnCount = new ArrayList<>();
+            columnCount.add(30);
+            columnCount.add(columnData.size());
+            univerSheet.setColumnCount(Collections.max(columnCount));
+            univerSheet.setShowGridlines(sheet.isDisplayGridlines() ? 1 : 0);
+
+            univerSheet.setSelections(ImmutableList.of("A1"));
+            univerSheet.setRightToLeft(0);
+            sheetList.add(univerSheet);
+        }
+
+        Map<String, UniverStyle> styles = styleMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
+        univerWorkBook.setStyles(styles);
+        Map<String, UniverSheet> sheetMap = sheetList.stream().collect(Collectors.toMap(UniverSheet::getId, Function.identity(), (s1, s2) -> s1, LinkedHashMap::new));
+        univerWorkBook.setSheetOrder(new ArrayList<>(sheetMap.keySet()));
+        univerWorkBook.setSheets(sheetMap);
+
+        //图片
+        Map<String, UniverResourceData> drawingMap = new HashMap<>();
+        //条件
+        Map<String, List<UniverResourceData>> formattingMap = new HashMap<>();
+        //数据管理
+        Map<String, List<UniverResourceData>> dataValidationMap = new HashMap<>();
+        //筛选
+        Map<String, UniverResourceData> filterMap = new HashMap<>();
+        //处理前端要的数据格式
+        univerSheetMap.forEach((key, value) -> {
+            Sheet sheet = workbook.getSheet(key);
+            if (sheet != null) {
+                //图片
+                drawingMap.putAll(excelParser.drawing(sheet, value, unitId));
+                //条件
+                formattingMap.putAll(excelParser.format(sheet, value, unitId));
+                //数据管理
+                dataValidationMap.putAll(excelParser.dataValidation(sheet, value, unitId));
+                //筛选
+                filterMap.putAll(excelParser.filter(sheet, value, unitId));
+            }
+        });
+        Map<String, String> resourceMap = new HashMap<>();
+        resourceMap.put(ResourceEnum.SHEET_DRAWING_PLUGIN.name(), JSONUtil.toJsonStr(drawingMap));
+        resourceMap.put(ResourceEnum.SHEET_CONDITIONAL_FORMATTING_PLUGIN.name(), JSONUtil.toJsonStr(formattingMap));
+        resourceMap.put(ResourceEnum.SHEET_DATA_VALIDATION_PLUGIN.name(), JSONUtil.toJsonStr(dataValidationMap));
+        resourceMap.put(ResourceEnum.SHEET_FILTER_PLUGIN.name(), JSONUtil.toJsonStr(filterMap));
+//        resourceMap.put(ResourceEnum.SHEET_DEFINED_NAME_PLUGIN.name(), JSONUtil.toJsonStr(definedNameMap));
+        univerWorkBook.setResources(getUniverResources(resourceMap));
+        return univerWorkBook;
+    }
+
+    private static List<UniverResource> getUniverResources(Map<String, String> resourceMap) {
+        List<UniverResource> resourcesList = new ArrayList<>();
+        for (ResourceEnum resource : ResourceEnum.values()) {
+            UniverResource model = new UniverResource();
+            String name = resource.name();
+            model.setName(name);
+            model.setData(resourceMap.get(name) != null ? resourceMap.get(name) : "{}");
+            resourcesList.add(model);
+        }
+        return resourcesList;
+    }
+
+    private static void link(Cell cell, Object value, Map<String, String> definedName, Map<String, String> univerSheetMap, UniverSheetCellData univerSheetCellData) {
+        Hyperlink link = cell.getHyperlink();
+        if (link != null) {
+            String address = link.getAddress();
+            if (StringUtil.isEmpty(address)) {
+                return;
+            }
+            //body
+            UniverBody body = new UniverBody();
+            String dataValue = value != null ? value.toString() : "";
+            if (StringUtil.isEmpty(dataValue)) {
+                return;
+            }
+            List<String> typeList = ImmutableList.of("\r\n", "\n", "\r");
+            for (String type : typeList) {
+                dataValue = StringUtils.removeEnd(dataValue, type);
+            }
+            int valueIndex = dataValue.length();
+            String dataStream = dataValue + "\r\n";
+            body.setDataStream(dataStream);
+            //customRanges
+            List<UniverBodyConfig> customRangesList = new ArrayList<>();
+            UniverBodyConfig customRanges = new UniverBodyConfig();
+            customRanges.setRangeId(RandomUtil.randomString(10));
+            customRanges.setRangeType(0);
+            customRanges.setStartIndex(0);
+            UniverBodyConfig properties = new UniverBodyConfig();
+            String[] split = address.split("!");
+            String url = Objects.equals(link.getType(), HyperlinkType.URL) ? address : definedName.get(address) != null ? "#rangeid=" + definedName.get(address) : "";
+            String linkSheetId = univerSheetMap.get(split[0]);
+            if (linkSheetId != null && split.length > 1) {
+                url = "#gid=" + linkSheetId + "&range=" + split[1];
+            }
+            properties.setUrl(url);
+            properties.setRefId(customRanges.getRangeId());
+            customRanges.setEndIndex(valueIndex > 0 ? valueIndex - 1 : valueIndex);
+            customRanges.setProperties(properties);
+            customRangesList.add(customRanges);
+            body.setCustomRanges(customRangesList);
+            //textRuns
+            body.setTextRuns(new ArrayList<>());
+            //customDecorations
+            body.setCustomDecorations(new ArrayList<>());
+            //sectionBreaks
+            List<UniverBodyConfig> sectionBreaksList = new ArrayList<>();
+            UniverBodyConfig sectionBreaks = new UniverBodyConfig();
+            sectionBreaks.setStartIndex(valueIndex + 1);
+            sectionBreaksList.add(sectionBreaks);
+            body.setSectionBreaks(sectionBreaksList);
+            //paragraphs
+            List<UniverBodyConfig> paragraphsList = new ArrayList<>();
+            UniverBodyConfig paragraphs = new UniverBodyConfig();
+            paragraphs.setStartIndex(valueIndex);
+            UniverBodyConfig paragraphStyle = new UniverBodyConfig();
+            paragraphStyle.setHorizontalAlign(0);
+            paragraphs.setParagraphStyle(paragraphStyle);
+            paragraphsList.add(paragraphs);
+            body.setParagraphs(paragraphsList);
+            UniverProperties p = new UniverProperties();
+            p.setBody(body);
+            p.setId("d");
+            univerSheetCellData.setP(p);
+            univerSheetCellData.setV(null);
+        }
+    }
+
+    private static Map<String, UniverResourceData> definedName(Workbook workbook, Map<String, String> definedName, Map<String, String> univerSheetMap) {
+        Map<String, UniverResourceData> definedNameMap = new HashMap<>();
+        for (Name name : workbook.getAllNames()) {
+            String definedId = RandomUtil.randomString(10);
+            String localSheetId = "AllDefaultWorkbook";
+            String nameName = name.getNameName();
+            int sheetIndex = name.getSheetIndex();
+            String sheetName = "";
+            if (sheetIndex > -1) {
+                Sheet sheetAt = workbook.getSheetAt(sheetIndex);
+                sheetName = sheetAt.getSheetName();
+                localSheetId = univerSheetMap.get(sheetName);
+            }
+            definedName.put(nameName + (StringUtil.isNotEmpty(sheetName) ? "!" + sheetName : ""), definedId);
+            UniverResourceData resourceData = new UniverResourceData();
+            resourceData.setId(definedId);
+            resourceData.setName(nameName);
+            resourceData.setFormulaOrRefString(name.getRefersToFormula());
+            resourceData.setComment(name.getComment());
+            resourceData.setLocalSheetId(localSheetId);
+            definedNameMap.put(definedId, resourceData);
+        }
+        return definedNameMap;
+    }
+
+}

+ 21 - 0
jnpf-datareport-univer-common/src/main/java/jnpf/util/excel/ImportExcelParser.java

@@ -0,0 +1,21 @@
+package jnpf.util.excel;
+
+import jnpf.univer.resources.UniverResourceData;
+import jnpf.univer.style.UniverStyle;
+import org.apache.poi.ss.usermodel.*;
+
+import java.util.*;
+
+public abstract class ImportExcelParser {
+    /**样式**/
+    public abstract UniverStyle getUniverStyle(CellStyle cellStyle, Workbook workbook);
+    /**筛选**/
+    public abstract Map<String, UniverResourceData> filter(Sheet sheet, String sheetId, String unitId);
+    /**数据管理**/
+    public abstract Map<String, List<UniverResourceData>> dataValidation(Sheet sheet, String sheetId, String unitId);
+    /**条件**/
+    public abstract Map<String, List<UniverResourceData>> format(Sheet sheet, String sheetId, String unitId);
+    /**图片**/
+    public abstract Map<String, UniverResourceData> drawing(Sheet sheet, String sheetId, String unitId);
+
+}

+ 397 - 0
jnpf-datareport-univer-common/src/main/java/jnpf/util/excel/ImportHssfExcel.java

@@ -0,0 +1,397 @@
+package jnpf.util.excel;
+
+import cn.hutool.core.img.ImgUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.RandomUtil;
+import jnpf.enums.*;
+import jnpf.univer.data.resource.*;
+import jnpf.univer.resources.UniverResourceData;
+import jnpf.univer.sheet.UniverSheetRange;
+import jnpf.univer.style.*;
+import org.apache.poi.hssf.model.HSSFFormulaParser;
+import org.apache.poi.hssf.model.InternalWorkbook;
+import org.apache.poi.hssf.record.NameRecord;
+import org.apache.poi.hssf.usermodel.*;
+import org.apache.poi.hssf.util.HSSFColor;
+import org.apache.poi.ss.formula.ptg.Ptg;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.CellRangeAddressList;
+
+import java.awt.image.BufferedImage;
+import java.util.*;
+
+public class ImportHssfExcel extends ImportExcelParser {
+
+    @Override
+    public UniverStyle getUniverStyle(CellStyle cellStyle, Workbook workbook) {
+        UniverStyle univerStyle = new UniverStyle();
+        if (cellStyle instanceof HSSFCellStyle && workbook instanceof HSSFWorkbook) {
+            HSSFCellStyle hssfCellStyle = (HSSFCellStyle) cellStyle;
+            HSSFWorkbook hssfWorkbook = (HSSFWorkbook) workbook;
+            univerStyle.setHt(HorizontalEnum.getHorizontalCode(hssfCellStyle.getAlignment()));
+            univerStyle.setVt(VerticalEnum.getVerticalCode(hssfCellStyle.getVerticalAlignment()));
+            HSSFFont font = hssfCellStyle.getFont(workbook);
+            if (null != font) {
+                univerStyle.setFf(font.getFontName());
+                univerStyle.setFs((int) font.getFontHeightInPoints());
+                univerStyle.setIt(font.getItalic() ? 1 : 0);
+                univerStyle.setBl(font.getBold() ? 1 : 0);
+                HSSFColor color = font.getHSSFColor(hssfWorkbook);
+                if (null != color) {
+                    UniverStyleColor cl = new UniverStyleColor();
+                    cl.setRgb(rgb(color.getTriplet()));
+                    univerStyle.setCl(cl);
+                }
+                if (Objects.equals(font.getUnderline(), Font.U_SINGLE)) {
+                    UniverStyleTextDecoration ul = new UniverStyleTextDecoration();
+                    ul.setS(1);
+                    univerStyle.setUl(ul);
+                }
+                if (font.getStrikeout()) {
+                    UniverStyleTextDecoration st = new UniverStyleTextDecoration();
+                    st.setS(1);
+                    univerStyle.setSt(st);
+                }
+            }
+            if (null != hssfCellStyle.getDataFormatString()) {
+                UniverStylePattern pattern = new UniverStylePattern();
+                pattern.setPattern(hssfCellStyle.getDataFormatString());
+                univerStyle.setN(pattern);
+            }
+            univerStyle.setBd(getUniverStyleBorder(hssfCellStyle, hssfWorkbook));
+
+            HSSFColor bgColor = hssfCellStyle.getFillForegroundColorColor();
+            FillPatternType pattern = hssfCellStyle.getFillPattern();
+            if (null != bgColor && Objects.equals(pattern, FillPatternType.SOLID_FOREGROUND)) {
+                UniverStyleColor background = new UniverStyleColor();
+                background.setRgb(rgb(bgColor.getTriplet()));
+                univerStyle.setBg(background);
+            }
+
+            UniverStyleTextRotation univerStyleTextRotation = new UniverStyleTextRotation();
+            univerStyleTextRotation.setA(hssfCellStyle.getRotation());
+            univerStyle.setTr(univerStyleTextRotation);
+        }
+        return univerStyle;
+    }
+
+    @Override
+    public Map<String, UniverResourceData> filter(Sheet sheet, String sheetId, String unitId) {
+        Map<String, UniverResourceData> filterMap = new HashMap<>();
+        //todo 只有获取筛选的格子,没有提供筛选的内容
+        if (sheet instanceof HSSFSheet) {
+            HSSFSheet hssfSheet = (HSSFSheet) sheet;
+            HSSFWorkbook workbook = hssfSheet.getWorkbook();
+            int sheetIndex = workbook.getSheetIndex(sheet) + 1;
+            UniverResourceData data = new UniverResourceData();
+            InternalWorkbook internalWorkbook = workbook.getWorkbook();
+            if (internalWorkbook != null) {
+                NameRecord name = internalWorkbook.getSpecificBuiltinRecord((byte) 13, sheetIndex);
+                if (name != null) {
+                    Ptg[] nameDefinition = name.getNameDefinition();
+                    String formulaString = HSSFFormulaParser.toFormulaString(hssfSheet.getWorkbook(), nameDefinition);
+                    CellRangeAddress addresses = CellRangeAddress.valueOf(formulaString);
+                    UniverSheetRange ref = new UniverSheetRange();
+                    ref.setStartRow(addresses.getFirstRow());
+                    ref.setStartColumn(addresses.getFirstColumn());
+                    ref.setEndRow(addresses.getLastRow());
+                    ref.setEndColumn(addresses.getLastColumn());
+                    data.setRef(ref);
+                    List<UniverFilters> filterColumns = new ArrayList();
+                    data.setFilterColumns(filterColumns);
+                    List<Integer> cachedFilteredOut = new ArrayList<>();
+                    data.setCachedFilteredOut(cachedFilteredOut);
+                    filterMap.put(sheetId, data);
+                }
+            }
+        }
+        return filterMap;
+    }
+
+    @Override
+    public Map<String, List<UniverResourceData>> dataValidation(Sheet sheet, String sheetId, String unitId) {
+        Map<String, List<UniverResourceData>> dataValidationMap = new HashMap<>();
+        if (sheet instanceof HSSFSheet) {
+            HSSFSheet hssfSheet = (HSSFSheet) sheet;
+            List<UniverResourceData> dataValidationList = new ArrayList<>();
+            List<HSSFDataValidation> dataValidations = hssfSheet.getDataValidations();
+            for (HSSFDataValidation dataValidation : dataValidations) {
+                UniverResourceData resourceData = new UniverResourceData();
+                List<UniverSheetRange> ranges = new ArrayList<>();
+                resourceData.setRanges(ranges);
+                resourceData.setUid(RandomUtil.randomString(10));
+                CellRangeAddressList addressList = dataValidation.getRegions();
+                for (CellRangeAddress address : addressList.getGenericChildren()) {
+                    UniverSheetRange sheetRange = new UniverSheetRange();
+                    sheetRange.setStartRow(address.getFirstRow());
+                    sheetRange.setStartColumn(address.getFirstColumn());
+                    sheetRange.setEndRow(address.getLastRow());
+                    sheetRange.setEndColumn(address.getLastColumn());
+                    sheetRange.setSheetId(sheetId);
+                    sheetRange.setUnitId(unitId);
+                    ranges.add(sheetRange);
+                }
+                DVConstraint constraint = (DVConstraint) dataValidation.getValidationConstraint();
+                ValidationType validationType = ValidationType.getType(constraint.getValidationType());
+                resourceData.setType(validationType.getType());
+                operatorTypeEnum operator = Objects.equals(validationType, ValidationType.none) ? null : operatorTypeEnum.getOperator(constraint.getOperator());
+                resourceData.setOperator(operator != null ? operator.getOperatorType() : null);
+                String value1 = constraint.getValue1() != null ? constraint.getValue1().toString() : constraint.getFormula1();
+                String value2 = constraint.getValue2() != null ? constraint.getValue2().toString() : constraint.getFormula2();
+                resourceData.setFormula1(value1 != null ? value1.replaceAll("\"", "") : value1);
+                resourceData.setFormula2(value2 != null ? value2.replaceAll("\"", "") : value2);
+                if (dataValidation.getShowErrorBox()) {
+                    resourceData.setShowErrorMessage(true);
+                    resourceData.setError(dataValidation.getErrorBoxTitle());
+                    resourceData.setErrorStyle(Objects.equals(dataValidation.getErrorStyle(), 0) ? 1 : 2);
+                }
+                resourceData.setAllowBlank(dataValidation.getEmptyCellAllowed());
+                resourceData.setRenderMode(dataValidation.getSuppressDropDownArrow() ? null : 0);
+                dataValidationList.add(resourceData);
+            }
+            dataValidationMap.put(sheetId, dataValidationList);
+        }
+        return dataValidationMap;
+    }
+
+    @Override
+    public Map<String, List<UniverResourceData>> format(Sheet sheet, String sheetId, String unitId) {
+        Map<String, List<UniverResourceData>> formattingMap = new HashMap<>();
+        //todo 提供色阶、数据条、色阶方法,其他方法获取的数据有问题
+        List<UniverResourceData> formatList = new ArrayList<>();
+        if (sheet instanceof HSSFSheet) {
+            HSSFSheet hssfSheet = (HSSFSheet) sheet;
+            HSSFSheetConditionalFormatting formatting = hssfSheet.getSheetConditionalFormatting();
+            if (null != formatting) {
+                for (int i = 0; i < formatting.getNumConditionalFormattings(); i++) {
+                    HSSFConditionalFormatting format = formatting.getConditionalFormattingAt(i);
+                    UniverResourceData resourceData = new UniverResourceData();
+                    resourceData.setCfId(RandomUtil.randomString(10));
+                    CellRangeAddress[] formattingRanges = format.getFormattingRanges();
+                    List<UniverSheetRange> ranges = new ArrayList<>();
+                    resourceData.setRanges(ranges);
+                    for (CellRangeAddress rangeAddress : formattingRanges) {
+                        UniverSheetRange range = new UniverSheetRange();
+                        range.setStartRow(rangeAddress.getFirstRow());
+                        range.setStartColumn(rangeAddress.getFirstColumn());
+                        range.setEndRow(rangeAddress.getLastRow());
+                        range.setEndColumn(rangeAddress.getLastColumn());
+                        range.setUnitId(unitId);
+                        range.setSheetId(sheetId);
+                        ranges.add(range);
+                    }
+                    for (int num = 0; num < format.getNumberOfRules(); num++) {
+                        HSSFConditionalFormattingRule formatRule = format.getRule(num);
+                        HSSFIconMultiStateFormatting iconSet = formatRule.getMultiStateFormatting();
+                        if (iconSet != null) {
+                            boolean reverse = iconSet.isReversed();
+                            UniverRule rule = new UniverRule();
+                            List<UniverConfig> univerConfig = new ArrayList<>();
+                            rule.setType(FormatTypeEnum.iconSet.name());
+                            rule.setConfig(univerConfig);
+                            //显示数据条没有属性
+                            rule.setIsShowValue(false);
+                            String iconType = iconSet.getIconSet().name;
+                            HSSFConditionalFormattingThreshold[] cfvoList = iconSet.getThresholds();
+                            int iconId = 0;
+                            for (int k = cfvoList.length - 1; k >= 0; k--) {
+                                HSSFConditionalFormattingThreshold cfvo = cfvoList[k];
+                                UniverValue value = new UniverValue();
+                                String type = cfvo.getRangeType().name;
+                                String val = Objects.equals(SubTypeEnum.expression.getCode(), type) ? "=" + cfvo.getFormula().replaceAll("\"", "") : cfvo.getValue() + "";
+                                value.setValue(val);
+                                value.setType(type);
+                                UniverConfig config = new UniverConfig();
+                                config.setOperator(OperatorEnum.greaterThan.name());
+                                config.setIconId((reverse ? k : iconId) + "");
+                                config.setIconType(iconType);
+                                config.setValue(value);
+                                univerConfig.add(config);
+                                iconId++;
+                            }
+                            resourceData.setRule(rule);
+                        }
+
+                        HSSFDataBarFormatting dataBar = formatRule.getDataBarFormatting();
+                        if (dataBar != null) {
+                            UniverRule rule = new UniverRule();
+                            UniverConfig config = new UniverConfig();
+                            rule.setConfig(config);
+                            rule.setType(FormatTypeEnum.dataBar.name());
+                            //显示数据条没有属性
+                            rule.setIsShowValue(false);
+                            HSSFConditionalFormattingThreshold minThreshold = dataBar.getMinThreshold();
+                            UniverValue min = new UniverValue();
+                            min.setType(minThreshold.getRangeType().name);
+                            min.setValue(Objects.equals(SubTypeEnum.expression.getCode(), min.getType()) ? "=" + minThreshold.getFormula().replaceAll("\"", "") : minThreshold.getValue() + "");
+                            config.setMin(min);
+                            HSSFConditionalFormattingThreshold maxThreshold = dataBar.getMaxThreshold();
+                            UniverValue max = new UniverValue();
+                            max.setType(maxThreshold.getRangeType().name);
+                            max.setValue(Objects.equals(SubTypeEnum.expression.getCode(), max.getType()) ? "=" + maxThreshold.getFormula().replaceAll("\"", "") : maxThreshold.getValue() + "");
+                            config.setMax(max);
+                            config.setIsGradient(true);
+                            byte[] rgb = dataBar.getColor().getRGB();
+                            config.setPositiveColor(rgb(rgb));
+                            config.setNativeColor(rgb(rgb));
+                            resourceData.setRule(rule);
+                        }
+
+                        HSSFColorScaleFormatting colorScale = formatRule.getColorScaleFormatting();
+                        if (colorScale != null) {
+                            UniverRule rule = new UniverRule();
+                            List<UniverConfig> univerConfig = new ArrayList<>();
+                            rule.setType(FormatTypeEnum.colorScale.name());
+                            rule.setConfig(univerConfig);
+                            Map<Integer, UniverValue> colorValue = new HashMap<>();
+                            HSSFConditionalFormattingThreshold[] cfvoList = colorScale.getThresholds();
+                            for (int k = 0; k < cfvoList.length; k++) {
+                                HSSFConditionalFormattingThreshold cfvo = cfvoList[k];
+                                UniverValue value = new UniverValue();
+                                String type = cfvo.getRangeType().name;
+                                String val = Objects.equals(SubTypeEnum.expression.getCode(), type) ? "=" + cfvo.getFormula().replaceAll("\"", "") : cfvo.getValue() + "";
+                                value.setType(type);
+                                value.setValue(val);
+                                colorValue.put(k, value);
+                            }
+                            HSSFExtendedColor[] colorList = colorScale.getColors();
+                            Map<Integer, String> colorColor = new HashMap<>();
+                            for (int k = 0; k < colorList.length; k++) {
+                                HSSFExtendedColor ctColor = colorList[k];
+                                colorColor.put(k, rgb(ctColor.getRGB()));
+                            }
+                            for (Integer k : colorValue.keySet()) {
+                                UniverConfig config = new UniverConfig();
+                                config.setValue(colorValue.get(k));
+                                config.setColor(colorColor.get(k));
+                                config.setIndex(k);
+                                univerConfig.add(config);
+                            }
+                            resourceData.setRule(rule);
+                        }
+
+                        resourceData.setStopIfTrue(formatRule.getStopIfTrue());
+                        if (resourceData.getRule() == null) {
+                            continue;
+                        }
+                        formatList.add(resourceData);
+                    }
+                }
+            }
+            formattingMap.put(sheetId, formatList);
+        }
+        return formattingMap;
+    }
+
+    @Override
+    public Map<String, UniverResourceData> drawing(Sheet sheet, String sheetId, String unitId) {
+        Map<String, UniverResourceData> drawingMap = new HashMap<>();
+        if (sheet instanceof HSSFSheet) {
+            HSSFSheet hssfSheet = (HSSFSheet) sheet;
+            List<String> order = new ArrayList<>();
+            Map<String, UniverDrawing> data = new HashMap<>();
+            HSSFPatriarch drawing = hssfSheet.getDrawingPatriarch();
+            if (drawing != null) {
+                List<HSSFShape> shapes = drawing.getChildren();
+                for (HSSFShape shape : shapes) {
+                    if (shape instanceof HSSFPicture) {
+                        HSSFPicture picture = (HSSFPicture) shape;
+                        byte[] pictureData = picture.getPictureData().getData();
+                        if (pictureData.length > 0) {
+                            String drawingId = RandomUtil.randomString(10);
+                            order.add(drawingId);
+                            BufferedImage image = ImgUtil.toImage(pictureData);
+                            UniverTransform sheetTransform = new UniverTransform();
+                            HSSFClientAnchor anchor = picture.getClientAnchor();
+                            UniverOffset univerFrom = new UniverOffset();
+                            univerFrom.setRow(anchor.getRow1());
+                            univerFrom.setColumn((int) anchor.getCol1());
+                            sheetTransform.setFrom(univerFrom);
+                            UniverOffset univerTo = new UniverOffset();
+                            univerTo.setRow(anchor.getRow2());
+                            univerTo.setColumn((int) anchor.getCol2());
+                            sheetTransform.setTo(univerTo);
+                            UniverDrawing univerDrawing = new UniverDrawing();
+                            univerDrawing.setSheetTransform(sheetTransform);
+                            univerDrawing.setDrawingType(0);
+                            univerDrawing.setUnitId(unitId);
+                            univerDrawing.setSubUnitId(sheetId);
+                            univerDrawing.setDrawingId(drawingId);
+                            univerDrawing.setImageSourceType(ImageEnum.BASE64.name());
+                            univerDrawing.setSource("data:image/jpeg;base64," + ImgUtil.toBase64(image, "jpeg"));
+                            data.put(drawingId, univerDrawing);
+                        }
+                    }
+                }
+            }
+            if (!order.isEmpty()) {
+                UniverResourceData resourceData = new UniverResourceData();
+                resourceData.setData(data);
+                resourceData.setOrder(order);
+                drawingMap.put(sheetId, resourceData);
+            }
+        }
+        return drawingMap;
+    }
+
+
+    private String rgb(short[] color) {
+        String rgb = null;
+        if (null != color && color.length == 3) {
+            rgb = String.format("#%02X%02X%02X", color[0], color[1], color[2]);
+        }
+        return rgb;
+    }
+
+    private String rgb(byte[] color) {
+        String rgb = null;
+        if (ObjectUtil.isNotEmpty(color)) {
+            rgb = String.format("#%02X%02X%02X", color[0], color[1], color[2]);
+        }
+        return rgb;
+    }
+
+    private UniverStyleBorder getUniverStyleBorder(HSSFCellStyle cellStyle, HSSFWorkbook workbook) {
+        UniverStyleBorder univerStyleBorder = new UniverStyleBorder();
+        int num = 0;
+        HSSFPalette palette = workbook.getCustomPalette();
+        HSSFColor leftBorder = palette.getColor(cellStyle.getLeftBorderColor());
+        if (null != leftBorder) {
+            UniverStyleBorderStyle left = new UniverStyleBorderStyle();
+            UniverStyleColor leftColor = new UniverStyleColor();
+            leftColor.setRgb(rgb(leftBorder.getTriplet()));
+            left.setCl(leftColor);
+            univerStyleBorder.setL(left);
+            num++;
+        }
+        HSSFColor topBorder = palette.getColor(cellStyle.getTopBorderColor());
+        if (null != topBorder) {
+            UniverStyleBorderStyle top = new UniverStyleBorderStyle();
+            UniverStyleColor topColor = new UniverStyleColor();
+            topColor.setRgb(rgb(topBorder.getTriplet()));
+            top.setCl(topColor);
+            univerStyleBorder.setT(top);
+            num++;
+        }
+        HSSFColor rightBorder = palette.getColor(cellStyle.getRightBorderColor());
+        if (null != rightBorder) {
+            UniverStyleBorderStyle right = new UniverStyleBorderStyle();
+            UniverStyleColor rightColor = new UniverStyleColor();
+            rightColor.setRgb(rgb(rightBorder.getTriplet()));
+            right.setCl(rightColor);
+            univerStyleBorder.setR(right);
+            num++;
+        }
+        HSSFColor bottomBorder = palette.getColor(cellStyle.getBottomBorderColor());
+        if (null != bottomBorder) {
+            UniverStyleBorderStyle bottom = new UniverStyleBorderStyle();
+            UniverStyleColor bottomColor = new UniverStyleColor();
+            bottomColor.setRgb(rgb(bottomBorder.getTriplet()));
+            bottom.setCl(bottomColor);
+            univerStyleBorder.setB(bottom);
+            num++;
+        }
+        return num > 0 ? univerStyleBorder : null;
+    }
+}

+ 557 - 0
jnpf-datareport-univer-common/src/main/java/jnpf/util/excel/ImportXssfExcel.java

@@ -0,0 +1,557 @@
+package jnpf.util.excel;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.img.ImgUtil;
+import cn.hutool.core.util.RandomUtil;
+import com.google.common.collect.ImmutableList;
+import jnpf.enums.*;
+import jnpf.univer.data.resource.*;
+import jnpf.univer.resources.UniverResourceData;
+import jnpf.univer.sheet.UniverSheetRange;
+import jnpf.univer.style.*;
+import jnpf.util.StringUtil;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.CellRangeAddressList;
+import org.apache.poi.xssf.model.StylesTable;
+import org.apache.poi.xssf.usermodel.*;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
+
+import java.awt.image.BufferedImage;
+import java.math.BigDecimal;
+import java.util.*;
+
+public class ImportXssfExcel extends ImportExcelParser {
+
+
+    @Override
+    public UniverStyle getUniverStyle(CellStyle cellStyle, Workbook workbook) {
+        UniverStyle univerStyle = new UniverStyle();
+        if (cellStyle instanceof XSSFCellStyle) {
+            XSSFCellStyle xssfCellStyle = (XSSFCellStyle) cellStyle;
+            univerStyle.setHt(HorizontalEnum.getHorizontalCode(xssfCellStyle.getAlignment()));
+            univerStyle.setVt(VerticalEnum.getVerticalCode(xssfCellStyle.getVerticalAlignment()));
+            XSSFFont font = xssfCellStyle.getFont();
+            if (null != font) {
+                univerStyle.setFf(font.getFontName());
+                univerStyle.setFs((int) font.getFontHeightInPoints());
+                univerStyle.setIt(font.getItalic() ? 1 : 0);
+                univerStyle.setBl(font.getBold() ? 1 : 0);
+                XSSFColor color = font.getXSSFColor();
+                if (null != color) {
+                    UniverStyleColor cl = new UniverStyleColor();
+                    cl.setRgb(rgb(color.getARGBHex()));
+                    univerStyle.setCl(cl);
+                }
+                if (Objects.equals(font.getUnderline(), Font.U_SINGLE)) {
+                    UniverStyleTextDecoration ul = new UniverStyleTextDecoration();
+                    ul.setS(1);
+                    univerStyle.setUl(ul);
+                }
+                if (font.getStrikeout()) {
+                    UniverStyleTextDecoration st = new UniverStyleTextDecoration();
+                    st.setS(1);
+                    univerStyle.setSt(st);
+                }
+            }
+            if (null != xssfCellStyle.getDataFormatString()) {
+                UniverStylePattern pattern = new UniverStylePattern();
+                pattern.setPattern(xssfCellStyle.getDataFormatString());
+                univerStyle.setN(pattern);
+            }
+            univerStyle.setBd(getUniverStyleBorder(xssfCellStyle));
+
+            XSSFColor bgColor = xssfCellStyle.getFillForegroundColorColor();
+            FillPatternType pattern = xssfCellStyle.getFillPattern();
+            if (null != bgColor && Objects.equals(pattern, FillPatternType.SOLID_FOREGROUND)) {
+                UniverStyleColor background = new UniverStyleColor();
+                background.setRgb(rgb(bgColor.getARGBHex()));
+                univerStyle.setBg(background);
+            }
+
+            UniverStyleTextRotation univerStyleTextRotation = new UniverStyleTextRotation();
+            univerStyleTextRotation.setA(xssfCellStyle.getRotation());
+            univerStyle.setTr(univerStyleTextRotation);
+        }
+        return univerStyle;
+    }
+
+    @Override
+    public Map<String, UniverResourceData> filter(Sheet sheet, String sheetId, String unitId) {
+        Map<String, UniverResourceData> filterMap = new HashMap<>();
+        if (sheet instanceof XSSFSheet) {
+            XSSFSheet xssfSheet = (XSSFSheet) sheet;
+            CTAutoFilter autoFilter = xssfSheet.getCTWorksheet().getAutoFilter();
+            UniverResourceData data = new UniverResourceData();
+            if (autoFilter != null && StringUtil.isNotEmpty(autoFilter.getRef())) {
+                CellRangeAddress addresses = CellRangeAddress.valueOf(autoFilter.getRef());
+                UniverSheetRange ref = new UniverSheetRange();
+                ref.setStartRow(addresses.getFirstRow());
+                ref.setStartColumn(addresses.getFirstColumn());
+                ref.setEndRow(addresses.getLastRow());
+                ref.setEndColumn(addresses.getLastColumn());
+                data.setRef(ref);
+                List<Integer> cachedFilteredOut = new ArrayList<>();
+                //隐藏行
+                for (int rowIndex = addresses.getFirstRow(); rowIndex <= addresses.getLastRow(); rowIndex++) {
+                    XSSFRow row = xssfSheet.getRow(rowIndex);
+                    if (row != null && row.getZeroHeight()) {
+                        cachedFilteredOut.add(rowIndex);
+                    }
+                }
+                //筛选条件
+                List<CTFilterColumn> filterColumnList = autoFilter.getFilterColumnList();
+                List<UniverFilters> filterColumns = new ArrayList<>();
+                for (CTFilterColumn filterColumn : filterColumnList) {
+                    UniverFilters univerFilters = new UniverFilters();
+                    univerFilters.setColId(filterColumn.getColId());
+
+                    //poi方法
+                    CTFilters ctFilters = filterColumn.getFilters();
+                    if (BeanUtil.isNotEmpty(ctFilters)) {
+                        UniverCustomFilters univerCustomFilters = new UniverCustomFilters();
+                        univerFilters.setFilters(univerCustomFilters);
+                        univerCustomFilters.setAnd(ctFilters.getBlank() ? 1 : null);
+                        List<CTFilter> filtersFilterList = ctFilters.getFilterList();
+                        for (CTFilter ctFilter : filtersFilterList) {
+                            String val = ctFilter.getVal();
+                            ArrayList<String> strings = new ArrayList<>();
+                            strings.add(val);
+                            univerCustomFilters.setFilters(strings);
+                        }
+                        filterColumns.add(univerFilters);
+
+                    }
+
+                    CTCustomFilters filters = filterColumn.getCustomFilters();
+                    if (null != filters) {
+                        UniverCustomFilters customFilters = new UniverCustomFilters();
+
+                        univerFilters.setCustomFilters(customFilters);
+
+                        List<UniverCustomFilters> customFilterList = new ArrayList<>();
+                        customFilters.setCustomFilters(customFilterList);
+                        customFilters.setAnd(filters.getAnd() ? 1 : null);
+                        List<CTCustomFilter> filterList = filters.getCustomFilterList();
+                        for (CTCustomFilter filter : filterList) {
+                            UniverCustomFilters univerCustomFilter = new UniverCustomFilters();
+                            univerCustomFilter.setVal(filter.getVal());
+//                        univerCustomFilter.setOperator(filter.getOperator() != null ? filter.getOperator().toString() : null);
+                            customFilterList.add(univerCustomFilter);
+                        }
+                        filterColumns.add(univerFilters);
+                    }
+                }
+                data.setFilterColumns(filterColumns);
+                data.setCachedFilteredOut(cachedFilteredOut);
+                filterMap.put(sheetId, data);
+            }
+        }
+        return filterMap;
+    }
+
+    @Override
+    public Map<String, List<UniverResourceData>> dataValidation(Sheet sheet, String sheetId, String unitId) {
+        Map<String, List<UniverResourceData>> dataValidationMap = new HashMap<>();
+        if (sheet instanceof XSSFSheet) {
+            XSSFSheet xssfSheet = (XSSFSheet) sheet;
+            List<UniverResourceData> dataValidationList = new ArrayList<>();
+            List<XSSFDataValidation> dataValidations = xssfSheet.getDataValidations();
+            for (XSSFDataValidation dataValidation : dataValidations) {
+                UniverResourceData resourceData = new UniverResourceData();
+                List<UniverSheetRange> ranges = new ArrayList<>();
+                resourceData.setRanges(ranges);
+                resourceData.setUid(RandomUtil.randomString(10));
+                CellRangeAddressList addressList = dataValidation.getRegions();
+                for (CellRangeAddress address : addressList.getGenericChildren()) {
+                    UniverSheetRange sheetRange = new UniverSheetRange();
+                    sheetRange.setStartRow(address.getFirstRow());
+                    sheetRange.setStartColumn(address.getFirstColumn());
+                    sheetRange.setEndRow(address.getLastRow());
+                    sheetRange.setEndColumn(address.getLastColumn());
+                    sheetRange.setSheetId(sheetId);
+                    sheetRange.setUnitId(unitId);
+                    ranges.add(sheetRange);
+                }
+                DataValidationConstraint constraint = dataValidation.getValidationConstraint();
+                ValidationType validationType = ValidationType.getType(constraint.getValidationType());
+                resourceData.setType(validationType.getType());
+                operatorTypeEnum operator = Objects.equals(validationType, ValidationType.none) ? null : operatorTypeEnum.getOperator(constraint.getOperator());
+                resourceData.setOperator(operator != null ? operator.getOperatorType() : null);
+                String value1 = constraint.getFormula1();
+                String value2 = constraint.getFormula2();
+                resourceData.setFormula1(value1 != null ? value1.replaceAll("\"", "") : value1);
+                resourceData.setFormula2(value2 != null ? value2.replaceAll("\"", "") : value2);
+                if (dataValidation.getShowErrorBox()) {
+                    resourceData.setShowErrorMessage(true);
+                    resourceData.setError(dataValidation.getErrorBoxTitle());
+                    resourceData.setErrorStyle(Objects.equals(dataValidation.getErrorStyle(), 0) ? 1 : 2);
+                }
+                resourceData.setAllowBlank(dataValidation.getEmptyCellAllowed());
+                resourceData.setRenderMode(dataValidation.getSuppressDropDownArrow() ? null : 0);
+                dataValidationList.add(resourceData);
+            }
+            dataValidationMap.put(sheetId, dataValidationList);
+        }
+        return dataValidationMap;
+    }
+
+    @Override
+    public Map<String, List<UniverResourceData>> format(Sheet sheet, String sheetId, String unitId) {
+        Map<String, List<UniverResourceData>> formattingMap = new HashMap<>();
+        List<UniverResourceData> formatList = new ArrayList<>();
+        if (sheet instanceof XSSFSheet) {
+            XSSFSheet xssfSheet = (XSSFSheet) sheet;
+            StylesTable styles = xssfSheet.getWorkbook().getStylesSource();
+            List<CTConditionalFormatting> conditionalFormatting = xssfSheet.getCTWorksheet().getConditionalFormattingList();
+            for (CTConditionalFormatting conditional : conditionalFormatting) {
+                UniverResourceData resourceData = new UniverResourceData();
+                resourceData.setCfId(RandomUtil.randomString(10));
+                List<UniverSheetRange> ranges = new ArrayList<>();
+                resourceData.setRanges(ranges);
+                List<String> formattingRanges = conditional.getSqref();
+                for (String range : formattingRanges) {
+                    UniverSheetRange sheetRange = new UniverSheetRange();
+                    CellRangeAddress rangeAddress = CellRangeAddress.valueOf(range);
+                    sheetRange.setStartRow(rangeAddress.getFirstRow());
+                    sheetRange.setStartColumn(rangeAddress.getFirstColumn());
+                    sheetRange.setEndRow(rangeAddress.getLastRow());
+                    sheetRange.setEndColumn(rangeAddress.getLastColumn());
+                    sheetRange.setUnitId(unitId);
+                    sheetRange.setSheetId(sheetId);
+                    ranges.add(sheetRange);
+                }
+                List<CTCfRule> cfRuleList = conditional.getCfRuleList();
+                for (CTCfRule cfRule : cfRuleList) {
+                    CTIconSet iconSet = cfRule.getIconSet();
+                    if (iconSet != null) {
+                        boolean reverse = iconSet.getReverse();
+                        UniverRule rule = new UniverRule();
+                        List<UniverConfig> univerConfig = new ArrayList<>();
+                        rule.setType(FormatTypeEnum.iconSet.name());
+                        rule.setConfig(univerConfig);
+                        rule.setIsShowValue(iconSet.getShowValue());
+                        String iconType = iconSet.getIconSet().toString();
+                        List<CTCfvo> cfvoList = iconSet.getCfvoList();
+                        int iconId = 0;
+                        for (int k = cfvoList.size() - 1; k >= 0; k--) {
+                            CTCfvo cfvo = cfvoList.get(k);
+                            UniverValue value = new UniverValue();
+                            String type = cfvo.getType().toString();
+                            String cfValue = cfvo.getVal() != null ? cfvo.getVal().toString() : "";
+                            String val = (Objects.equals(SubTypeEnum.expression.getType(), type) ? "=" : "") + cfValue.replaceAll("\"", "");
+                            value.setValue(val);
+                            value.setType(type);
+                            UniverConfig config = new UniverConfig();
+                            config.setOperator(cfvo.getGte() ? OperatorEnum.greaterThanOrEqual.name() : OperatorEnum.greaterThan.name());
+                            config.setIconId((reverse ? k : iconId) + "");
+                            config.setIconType(iconType);
+                            config.setValue(value);
+                            univerConfig.add(config);
+                            iconId++;
+                        }
+                        resourceData.setRule(rule);
+                    }
+                    CTDataBar dataBar = cfRule.getDataBar();
+                    if (dataBar != null) {
+                        UniverRule rule = new UniverRule();
+                        UniverConfig config = new UniverConfig();
+                        rule.setConfig(config);
+                        rule.setType(FormatTypeEnum.dataBar.name());
+                        rule.setIsShowValue(dataBar.getShowValue());
+                        List<CTCfvo> cfvoList = dataBar.getCfvoList();
+                        UniverValue min = new UniverValue();
+                        min.setType(OperatorEnum.min.name());
+                        config.setMin(min);
+                        UniverValue max = new UniverValue();
+                        max.setType(OperatorEnum.max.name());
+                        config.setMax(max);
+                        for (int k = 0; k < cfvoList.size(); k++) {
+                            CTCfvo cfvo = cfvoList.get(k);
+                            String type = cfvo.getType().toString();
+                            String cfValue = cfvo.getVal() != null ? cfvo.getVal().toString() : "";
+                            String val = (Objects.equals(SubTypeEnum.expression.getType(), type) ? "=" : "") + cfValue.replaceAll("\"", "");
+                            if (k == 0) {
+                                min.setValue(val);
+                                min.setType(type);
+                            } else {
+                                max.setValue(val);
+                                max.setType(Objects.equals(type, OperatorEnum.min.name()) ? max.getType() : type);
+                            }
+                        }
+                        config.setIsGradient(false);
+                        CTColor ctColor = dataBar.getColor();
+                        if (ctColor != null) {
+                            XSSFColor color = new XSSFColor(ctColor.getRgb());
+                            String colorRgb = rgb(color.getARGBHex());
+                            config.setPositiveColor(colorRgb);
+                            config.setNativeColor(colorRgb);
+                        }
+                        resourceData.setRule(rule);
+                    }
+                    CTColorScale colorScale = cfRule.getColorScale();
+                    if (colorScale != null) {
+                        UniverRule rule = new UniverRule();
+                        List<UniverConfig> univerConfig = new ArrayList<>();
+                        rule.setType(FormatTypeEnum.colorScale.name());
+                        rule.setConfig(univerConfig);
+                        Map<Integer, UniverValue> colorValue = new HashMap<>();
+                        List<CTCfvo> cfvoList = colorScale.getCfvoList();
+                        for (int k = 0; k < cfvoList.size(); k++) {
+                            CTCfvo cfvo = cfvoList.get(k);
+                            UniverValue value = new UniverValue();
+                            String type = cfvo.getType().toString();
+                            String cfValue = cfvo.getVal() != null ? cfvo.getVal().toString() : "";
+                            String val = (Objects.equals(SubTypeEnum.expression.getType(), type) ? "=" : "") + cfValue.replaceAll("\"", "");
+                            value.setType(type);
+                            value.setValue(val);
+                            colorValue.put(k, value);
+                        }
+                        List<CTColor> colorList = colorScale.getColorList();
+                        Map<Integer, String> colorColor = new HashMap<>();
+                        for (int k = 0; k < colorList.size(); k++) {
+                            CTColor ctColor = colorList.get(k);
+                            XSSFColor color = new XSSFColor(ctColor.getRgb());
+                            String colorRgb = rgb(color.getARGBHex());
+                            colorColor.put(k, colorRgb);
+                        }
+                        for (Integer k : colorValue.keySet()) {
+                            UniverConfig config = new UniverConfig();
+                            config.setValue(colorValue.get(k));
+                            config.setColor(colorColor.get(k));
+                            config.setIndex(k);
+                            univerConfig.add(config);
+                        }
+                        resourceData.setRule(rule);
+                    }
+                    CTCfRule highlightCell = cfRule;
+                    if (highlightCell != null) {
+                        String type = highlightCell.getType().toString();
+                        SubTypeEnum subTypeEnum = SubTypeEnum.getType(type);
+                        if (subTypeEnum != null) {
+                            UniverRule rule = new UniverRule();
+                            rule.setType(FormatTypeEnum.highlightCell.name());
+                            boolean isUnique = ImmutableList.of(SubTypeEnum.uniqueValues.getType(), SubTypeEnum.duplicateValues.getType()).contains(subTypeEnum.getType());
+                            boolean isNumber = Objects.equals(SubTypeEnum.cellIs.getType(), subTypeEnum.getType());
+                            boolean isAverage = Objects.equals(SubTypeEnum.aboveAverage.getType(), subTypeEnum.getType());
+                            boolean isRank = Objects.equals(SubTypeEnum.top10.getType(), subTypeEnum.getType());
+                            boolean isFormula = Objects.equals(SubTypeEnum.expression.getType(), subTypeEnum.getType());
+                            boolean isTime = Objects.equals(SubTypeEnum.timePeriod.getType(), subTypeEnum.getType());
+                            List<String> dataList = highlightCell.getFormulaList() != null ? highlightCell.getFormulaList() : new ArrayList<>();
+                            List<BigDecimal> numberDataList = new ArrayList<>();
+                            BigDecimal numberData = null;
+                            String textValue = "";
+                            for (String data : dataList) {
+                                try {
+                                    BigDecimal bigDecimal = new BigDecimal(data);
+                                    numberDataList.add(bigDecimal);
+                                    numberData = bigDecimal;
+                                } catch (Exception e) {
+                                    textValue = data;
+                                }
+                            }
+                            if (isNumber) {
+                                if (highlightCell.getOperator() != null) {
+                                    rule.setOperator(highlightCell.getOperator().toString());
+                                }
+                                boolean isText = numberDataList.isEmpty();
+                                rule.setSubType(isText ? SubTypeEnum.text.getCode() : SubTypeEnum.cellIs.getCode());
+                                rule.setValue(isText ? textValue : numberDataList.size() > 1 ? numberDataList : numberData);
+                            } else if (isAverage) {
+                                rule.setSubType(subTypeEnum.getCode());
+                                rule.setOperator(highlightCell.getAboveAverage() ? OperatorEnum.greaterThan.name() : OperatorEnum.lessThan.name());
+                            } else if (isRank) {
+                                rule.setSubType(subTypeEnum.getCode());
+                                rule.setIsPercent(highlightCell.getPercent());
+                                rule.setIsBottom(highlightCell.getBottom());
+                                rule.setValue(highlightCell.getRank() + "");
+                            } else if (isFormula) {
+                                rule.setSubType(SubTypeEnum.expression.getCode());
+                                rule.setValue("=" + textValue.replaceAll("\"", ""));
+                            } else if (isTime) {
+                                rule.setSubType(subTypeEnum.getCode());
+                                rule.setOperator(highlightCell.getTimePeriod().toString());
+                            } else if (isUnique) {
+                                rule.setSubType(subTypeEnum.getType());
+                            } else {
+                                rule.setSubType(SubTypeEnum.text.getCode());
+                                rule.setOperator(highlightCell.getOperator() != null ? highlightCell.getOperator().toString() : subTypeEnum.getType());
+                                if (highlightCell.getText() != null) {
+                                    rule.setValue(highlightCell.getText());
+                                }
+                            }
+                            UniverStyle style = new UniverStyle();
+                            CTDxf dxf = highlightCell.isSetDxfId() ? styles.getDxfAt((int) highlightCell.getDxfId()) : null;
+                            if (dxf != null) {
+                                CTFill ctFill = dxf.getFill();
+                                if (ctFill != null) {
+                                    CTPatternFill patternFill = ctFill.getPatternFill();
+                                    if (patternFill != null) {
+                                        XSSFColor baColor = XSSFColor.from(patternFill.getBgColor());
+                                        if (baColor != null) {
+                                            UniverStyleColor bg = new UniverStyleColor();
+                                            bg.setRgb(rgb(baColor.getARGBHex()));
+                                            style.setBg(bg);
+                                        }
+                                    }
+                                }
+                                CTFont ctFont = dxf.getFont();
+                                if (ctFont != null) {
+                                    XSSFColor fontColor = ctFont.sizeOfColorArray() > 0 ? XSSFColor.from(ctFont.getColorArray(0)) : null;
+                                    if (fontColor != null) {
+                                        UniverStyleColor cl = new UniverStyleColor();
+                                        cl.setRgb(rgb(fontColor.getARGBHex()));
+                                        style.setCl(cl);
+                                    }
+                                    STUnderlineValues.Enum underlineType = ctFont.sizeOfUArray() == 1 ? ctFont.getUArray(0).getVal() : STUnderlineValues.NONE;
+                                    if (Objects.equals(underlineType, STUnderlineValues.SINGLE)) {
+                                        UniverStyleTextDecoration ul = new UniverStyleTextDecoration();
+                                        ul.setS(1);
+                                        style.setUl(ul);
+                                    }
+                                    boolean strike = ctFont.sizeOfStrikeArray() > 0 && ctFont.getStrikeArray(0).getVal();
+                                    if (strike) {
+                                        UniverStyleTextDecoration st = new UniverStyleTextDecoration();
+                                        st.setS(1);
+                                        style.setSt(st);
+                                    }
+                                    boolean isItalic = ctFont.sizeOfIArray() == 1 && ctFont.getIArray(0).getVal();
+                                    boolean isBold = ctFont.sizeOfBArray() == 1 && ctFont.getBArray(0).getVal();
+                                    style.setIt(isItalic ? 1 : 0);
+                                    style.setBl(isBold ? 1 : 0);
+                                }
+                            }
+                            rule.setStyle(style);
+                            resourceData.setRule(rule);
+                        }
+                    }
+                    resourceData.setStopIfTrue(cfRule.getStopIfTrue());
+                    if (resourceData.getRule() == null) {
+                        continue;
+                    }
+                    formatList.add(resourceData);
+                }
+            }
+            formattingMap.put(sheetId, formatList);
+        }
+        return formattingMap;
+    }
+
+    @Override
+    public Map<String, UniverResourceData> drawing(Sheet sheet, String sheetId, String unitId) {
+        Map<String, UniverResourceData> drawingMap = new HashMap<>();
+        if (sheet instanceof XSSFSheet) {
+            XSSFSheet xssfSheet = (XSSFSheet) sheet;
+            List<String> order = new ArrayList<>();
+            Map<String, UniverDrawing> data = new HashMap<>();
+            XSSFDrawing drawing = xssfSheet.getDrawingPatriarch();
+            if (drawing != null) {
+                List<XSSFShape> shapes = drawing.getShapes();
+                for (XSSFShape shape : shapes) {
+                    if (shape instanceof XSSFPicture) {
+                        XSSFPicture picture = (XSSFPicture) shape;
+                        byte[] pictureData = picture.getPictureData().getData();
+                        if (pictureData.length > 0) {
+                            String drawingId = RandomUtil.randomString(10);
+                            order.add(drawingId);
+                            BufferedImage image = ImgUtil.toImage(pictureData);
+                            UniverTransform sheetTransform = new UniverTransform();
+
+                            XSSFClientAnchor anchor = picture.getClientAnchor();
+                            UniverOffset univerFrom = new UniverOffset();
+                            univerFrom.setRowOffset(0);
+                            univerFrom.setColumnOffset(0);
+                            univerFrom.setRow(anchor.getRow1());
+                            univerFrom.setColumn((int) anchor.getCol1());
+                            sheetTransform.setFrom(univerFrom);
+                            UniverOffset univerTo = new UniverOffset();
+                            univerTo.setRowOffset(0);
+                            univerTo.setColumnOffset(0);
+                            univerTo.setRow(anchor.getRow2());
+                            univerTo.setColumn((int) anchor.getCol2());
+                            sheetTransform.setTo(univerTo);
+                            UniverDrawing univerDrawing = new UniverDrawing();
+                            univerDrawing.setSheetTransform(sheetTransform);
+                            UniverTransform transform = new UniverTransform();
+                            transform.setFlipX(false);
+                            transform.setFlipY(false);
+                            transform.setSkewX(0);
+                            transform.setSkewY(0);
+                            transform.setAngle(0);
+                            transform.setLeft(500);
+                            transform.setTop(500);
+                            transform.setHeight(500);
+                            transform.setWidth(500);
+                            univerDrawing.setTransform(transform);
+                            univerDrawing.setAllowTransform(true);
+                            univerDrawing.setDrawingType(0);
+                            univerDrawing.setUnitId(unitId);
+                            univerDrawing.setSubUnitId(sheetId);
+                            univerDrawing.setDrawingId(drawingId);
+                            univerDrawing.setImageSourceType(ImageEnum.BASE64.name());
+                            univerDrawing.setSource("data:image/jpeg;base64," + ImgUtil.toBase64(image, "jpeg"));
+                            data.put(drawingId, univerDrawing);
+                        }
+                    }
+                }
+            }
+            if (!order.isEmpty()) {
+                UniverResourceData resourceData = new UniverResourceData();
+                resourceData.setData(data);
+                resourceData.setOrder(order);
+                drawingMap.put(sheetId, resourceData);
+            }
+        }
+        return drawingMap;
+    }
+
+    private String rgb(String color) {
+        String rgb = null;
+        if (StringUtil.isNotEmpty(color)) {
+            rgb = "#" + color.substring(2, 8);
+        }
+        return rgb;
+    }
+
+    private UniverStyleBorder getUniverStyleBorder(XSSFCellStyle cellStyle) {
+        UniverStyleBorder univerStyleBorder = new UniverStyleBorder();
+        int num = 0;
+        XSSFColor leftBorder = cellStyle.getLeftBorderXSSFColor();
+        if (null != leftBorder) {
+            UniverStyleBorderStyle left = new UniverStyleBorderStyle();
+            UniverStyleColor leftColor = new UniverStyleColor();
+            leftColor.setRgb(rgb(leftBorder.getARGBHex()));
+            left.setCl(leftColor);
+            univerStyleBorder.setL(left);
+            num++;
+        }
+        XSSFColor topBorder = cellStyle.getTopBorderXSSFColor();
+        if (null != topBorder) {
+            UniverStyleBorderStyle top = new UniverStyleBorderStyle();
+            UniverStyleColor topColor = new UniverStyleColor();
+            topColor.setRgb(rgb(topBorder.getARGBHex()));
+            top.setCl(topColor);
+            univerStyleBorder.setT(top);
+            num++;
+        }
+        XSSFColor rightBorder = cellStyle.getRightBorderXSSFColor();
+        if (null != rightBorder) {
+            UniverStyleBorderStyle right = new UniverStyleBorderStyle();
+            UniverStyleColor rightColor = new UniverStyleColor();
+            rightColor.setRgb(rgb(rightBorder.getARGBHex()));
+            right.setCl(rightColor);
+            univerStyleBorder.setR(right);
+            num++;
+        }
+        XSSFColor bottomBorder = cellStyle.getBottomBorderXSSFColor();
+        if (null != bottomBorder) {
+            UniverStyleBorderStyle bottom = new UniverStyleBorderStyle();
+            UniverStyleColor bottomColor = new UniverStyleColor();
+            bottomColor.setRgb(rgb(bottomBorder.getARGBHex()));
+            bottom.setCl(bottomColor);
+            univerStyleBorder.setB(bottom);
+            num++;
+        }
+        return num > 0 ? univerStyleBorder : null;
+    }
+}

+ 686 - 0
jnpf-datareport-univer-common/src/main/java/jnpf/util/excel/UniverHSSFExcel.java

@@ -0,0 +1,686 @@
+package jnpf.util.excel;
+
+import cn.hutool.core.img.ImgUtil;
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.json.JSONUtil;
+import com.google.common.collect.ImmutableList;
+import jnpf.enums.*;
+import jnpf.univer.data.resource.*;
+import jnpf.univer.model.UniverWorkBook;
+import jnpf.univer.properties.UniverBody;
+import jnpf.univer.properties.UniverBodyConfig;
+import jnpf.univer.properties.UniverProperties;
+import jnpf.univer.resources.UniverResource;
+import jnpf.univer.resources.UniverResourceData;
+import jnpf.univer.sheet.*;
+import jnpf.univer.style.*;
+import jnpf.util.StringUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.common.usermodel.HyperlinkType;
+import org.apache.poi.hssf.model.HSSFFormulaParser;
+import org.apache.poi.hssf.model.InternalWorkbook;
+import org.apache.poi.hssf.record.NameRecord;
+import org.apache.poi.hssf.usermodel.*;
+import org.apache.poi.hssf.util.HSSFColor;
+import org.apache.poi.ss.formula.ptg.Ptg;
+import org.apache.poi.ss.usermodel.CellType;
+import org.apache.poi.ss.usermodel.FillPatternType;
+import org.apache.poi.ss.usermodel.Font;
+import org.apache.poi.ss.usermodel.Hyperlink;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.CellRangeAddressList;
+import org.apache.poi.ss.util.PaneInformation;
+
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/6/20 下午4:30
+ */
+public class UniverHSSFExcel extends ExcelParser {
+
+    @Override
+    public UniverWorkBook formFile(InputStream inputStream) throws IOException {
+        HSSFWorkbook workbook = new HSSFWorkbook(inputStream);
+        UniverWorkBook univerWorkBook = new UniverWorkBook();
+        String unitId = RandomUtil.randomString(10);
+        univerWorkBook.setId(unitId);
+        univerWorkBook.setName("");
+        Map<UniverStyle, String> styleMap = new HashMap<>();
+        List<UniverSheet> sheetList = new ArrayList<>();
+        //sheet名称对应的id
+        Map<String, String> univerSheetMap = new HashMap<>();
+        for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
+            String sheetId = RandomUtil.randomString(10);
+            HSSFSheet sheet = workbook.getSheetAt(i);
+            univerSheetMap.put(sheet.getSheetName(), sheetId);
+        }
+        Map<String, String> definedName = new HashMap<>();
+        Map<String, UniverResourceData> definedNameMap = definedName(workbook, definedName, univerSheetMap);
+        for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
+            HSSFSheet sheet = workbook.getSheetAt(i);
+            String sheetName = sheet.getSheetName();
+            String sheetId = univerSheetMap.get(sheetName);
+            UniverSheet univerSheet = new UniverSheet();
+            univerSheet.setId(sheetId);
+            univerSheet.setName(sheetName);
+            univerSheet.setHidden(!workbook.isSheetHidden(i) ? 0 : 1);
+            univerSheet.setTabColor("");
+            //冻结位置
+            UniverSheetFreeze sheetFreeze = new UniverSheetFreeze();
+            PaneInformation freeze = sheet.getPaneInformation();
+            if (freeze != null) {
+                int freezeColumn = freeze.getVerticalSplitLeftColumn();
+                if (freezeColumn > 0) {
+                    sheetFreeze.setStartColumn(freezeColumn);
+                    sheetFreeze.setXSplit(freezeColumn);
+                }
+                int freezeRow = freeze.getHorizontalSplitTopRow();
+                if (freezeRow > 0) {
+                    sheetFreeze.setStartRow(freezeRow);
+                    sheetFreeze.setYSplit(freezeRow);
+                }
+            }
+            univerSheet.setFreeze(sheetFreeze);
+
+            Map<Integer, UniverSheetRowData> rowData = new HashMap<>();
+            Map<Integer, UniverSheetColumnData> columnData = new HashMap<>();
+            Map<Integer, Map<Integer, UniverSheetCellData>> cellData = new HashMap<>();
+            for (int rowCount = 0; rowCount <= sheet.getLastRowNum(); rowCount++) {
+                HSSFRow row = sheet.getRow(rowCount);
+                Map<Integer, UniverSheetCellData> cells = new HashMap<>();
+                if (null != row) {
+                    for (int columnCount = 0; columnCount <= row.getLastCellNum(); columnCount++) {
+                        HSSFCell cell = row.getCell(columnCount);
+                        UniverSheetCellData univerSheetCellData = new UniverSheetCellData();
+                        if (null != cell) {
+                            //数据
+                            Object value = "";
+                            String formula = null;
+                            CellType cellType = cell.getCellType();
+                            Integer type = null;
+                            switch (cellType) {
+                                case STRING:
+                                    value = cell.getStringCellValue();
+                                    type = CellDataTypeEnum.String.getCode();
+                                    break;
+                                case BOOLEAN:
+                                    value = cell.getBooleanCellValue();
+                                    type = CellDataTypeEnum.Boolean.getCode();
+                                    break;
+                                case NUMERIC:
+                                    value = new BigDecimal(cell.getNumericCellValue());
+                                    type = CellDataTypeEnum.Number.getCode();
+                                    break;
+                                case FORMULA:
+                                    value = cell.getCellFormula();
+                                    formula = "=" + value;
+                                    type = CellDataTypeEnum.Formula.getCode();
+                                    break;
+                            }
+                            univerSheetCellData.setV(value);
+                            univerSheetCellData.setF(formula);
+                            univerSheetCellData.setT(type);
+                            //样式
+                            HSSFCellStyle cellStyle = cell.getCellStyle();
+                            UniverStyle style = getUniverStyle(cellStyle, workbook);
+                            String styleName = styleMap.get(style) != null ? styleMap.get(style) : RandomUtil.randomString(6);
+                            styleMap.put(style, styleName);
+                            univerSheetCellData.setS(styleName);
+                            cells.put(columnCount, univerSheetCellData);
+                            UniverSheetColumnData univerSheetColumnData = new UniverSheetColumnData();
+                            univerSheetColumnData.setHd(!sheet.isColumnHidden(columnCount) ? 0 : 1);
+                            List<Integer> colHeight = new ArrayList<>();
+                            colHeight.add(100);
+                            colHeight.add((int) sheet.getColumnWidthInPixels(columnCount));
+                            univerSheetColumnData.setW(Collections.max(colHeight));
+                            columnData.put(columnCount, univerSheetColumnData);
+                            link(cell, value, definedName, univerSheetMap, univerSheetCellData);
+                        }
+                    }
+                    cellData.put(rowCount, cells);
+                    UniverSheetRowData univerSheetRowData = new UniverSheetRowData();
+                    univerSheetRowData.setHd(!row.getZeroHeight() ? 0 : 1);
+                    List<Integer> rowHeight = new ArrayList<>();
+                    rowHeight.add(50);
+                    rowHeight.add((int) row.getHeightInPoints());
+                    univerSheetRowData.setH(Collections.max(rowHeight));
+                    univerSheetRowData.setIa(0);
+                    rowData.put(rowCount, univerSheetRowData);
+                }
+            }
+            univerSheet.setCellData(cellData);
+            univerSheet.setRowData(rowData);
+            univerSheet.setColumnData(columnData);
+
+            List<UniverSheetRange> mergeData = new ArrayList<>();
+            for (CellRangeAddress region : sheet.getMergedRegions()) {
+                UniverSheetRange univerSheetRange = new UniverSheetRange();
+                univerSheetRange.setStartRow(region.getFirstRow());
+                univerSheetRange.setStartColumn(region.getFirstColumn());
+                univerSheetRange.setEndRow(region.getLastRow());
+                univerSheetRange.setEndColumn(region.getLastColumn());
+                mergeData.add(univerSheetRange);
+            }
+            univerSheet.setMergeData(mergeData);
+
+            UniverSheetRowHeader univerSheetRowHeader = new UniverSheetRowHeader();
+            univerSheetRowHeader.setHidden(0);
+            univerSheetRowHeader.setWidth(46);
+            univerSheet.setRowHeader(univerSheetRowHeader);
+
+            UniverSheetColumnHeader univerSheetColumnHeader = new UniverSheetColumnHeader();
+            univerSheetColumnHeader.setHidden(0);
+            univerSheetColumnHeader.setHeight(20);
+            univerSheet.setColumnHeader(univerSheetColumnHeader);
+
+            univerSheet.setZoomRatio(1);
+            univerSheet.setScrollTop(0);
+            univerSheet.setScrollLeft(0);
+            univerSheet.setDefaultColumnWidth(88);
+            univerSheet.setDefaultRowHeight(24);
+            List<Integer> rowCount = new ArrayList<>();
+            rowCount.add(100);
+            rowCount.add(rowData.size());
+            univerSheet.setRowCount(Collections.max(rowCount));
+            List<Integer> columnCount = new ArrayList<>();
+            columnCount.add(30);
+            columnCount.add(columnData.size());
+            univerSheet.setColumnCount(Collections.max(columnCount));
+            univerSheet.setShowGridlines(sheet.isDisplayGridlines() ? 1 : 0);
+
+            univerSheet.setSelections(ImmutableList.of("A1"));
+            univerSheet.setRightToLeft(0);
+            sheetList.add(univerSheet);
+        }
+
+        Map<String, UniverStyle> styles = styleMap.entrySet().stream().collect(Collectors.toMap(t -> t.getValue(), t -> t.getKey()));
+        univerWorkBook.setStyles(styles);
+        Map<String, UniverSheet> sheetMap = sheetList.stream().collect(Collectors.toMap(UniverSheet::getId, Function.identity(), (s1, s2) -> s1, LinkedHashMap::new));
+        univerWorkBook.setSheetOrder(new ArrayList<>(sheetMap.keySet()));
+        univerWorkBook.setSheets(sheetMap);
+
+        //图片
+        Map<String, UniverResourceData> drawingMap = new HashMap<>();
+        //条件
+        Map<String, List<UniverResourceData>> formattingMap = new HashMap<>();
+        //数据管理
+        Map<String, List<UniverResourceData>> dataValidationMap = new HashMap<>();
+        //筛选
+        Map<String, UniverResourceData> filterMap = new HashMap<>();
+        //处理前端要的数据格式
+        univerSheetMap.forEach((key, value) -> {
+            HSSFSheet sheet = workbook.getSheet(key);
+            if (sheet != null) {
+                //图片
+                drawing(sheet, value, unitId, drawingMap);
+                //条件
+                format(sheet, value, unitId, formattingMap);
+                //数据管理
+                dataValidation(sheet, value, unitId, dataValidationMap);
+                //筛选
+                filter(sheet, value, unitId, filterMap);
+            }
+        });
+        Map<String, String> resourceMap = new HashMap<>();
+        resourceMap.put(ResourceEnum.SHEET_DRAWING_PLUGIN.name(), JSONUtil.toJsonStr(drawingMap));
+        resourceMap.put(ResourceEnum.SHEET_CONDITIONAL_FORMATTING_PLUGIN.name(), JSONUtil.toJsonStr(formattingMap));
+        resourceMap.put(ResourceEnum.SHEET_DATA_VALIDATION_PLUGIN.name(), JSONUtil.toJsonStr(dataValidationMap));
+        resourceMap.put(ResourceEnum.SHEET_FILTER_PLUGIN.name(), JSONUtil.toJsonStr(filterMap));
+//        resourceMap.put(ResourceEnum.SHEET_DEFINED_NAME_PLUGIN.name(), JSONUtil.toJsonStr(definedNameMap));
+        univerWorkBook.setResources(getUniverResources(resourceMap));
+        return univerWorkBook;
+    }
+
+    private UniverStyle getUniverStyle(HSSFCellStyle cellStyle, HSSFWorkbook workbook) {
+        UniverStyle univerStyle = new UniverStyle();
+        univerStyle.setHt(HorizontalEnum.getHorizontalCode(cellStyle.getAlignment()));
+        univerStyle.setVt(VerticalEnum.getVerticalCode(cellStyle.getVerticalAlignment()));
+
+        HSSFFont font = cellStyle.getFont(workbook);
+        if (null != font) {
+            univerStyle.setFf(font.getFontName());
+            univerStyle.setFs((int) font.getFontHeightInPoints());
+            univerStyle.setIt(font.getItalic() ? 1 : 0);
+            univerStyle.setBl(font.getBold() ? 1 : 0);
+            HSSFColor color = font.getHSSFColor(workbook);
+            if (null != color) {
+                UniverStyleColor cl = new UniverStyleColor();
+                cl.setRgb(rgb(color.getTriplet()));
+                univerStyle.setCl(cl);
+            }
+            if (Objects.equals(font.getUnderline(), Font.U_SINGLE)) {
+                UniverStyleTextDecoration ul = new UniverStyleTextDecoration();
+                ul.setS(1);
+                univerStyle.setUl(ul);
+            }
+            if (font.getStrikeout()) {
+                UniverStyleTextDecoration st = new UniverStyleTextDecoration();
+                st.setS(1);
+                univerStyle.setSt(st);
+            }
+        }
+        if (null != cellStyle.getDataFormatString()) {
+            UniverStylePattern pattern = new UniverStylePattern();
+            pattern.setPattern(cellStyle.getDataFormatString());
+            univerStyle.setN(pattern);
+        }
+        univerStyle.setBd(getUniverStyleBorder(cellStyle, workbook));
+
+        HSSFColor bgColor = cellStyle.getFillForegroundColorColor();
+        FillPatternType pattern = cellStyle.getFillPattern();
+        if (null != bgColor && Objects.equals(pattern, FillPatternType.SOLID_FOREGROUND)) {
+            UniverStyleColor background = new UniverStyleColor();
+            background.setRgb(rgb(bgColor.getTriplet()));
+            univerStyle.setBg(background);
+        }
+
+        UniverStyleTextRotation univerStyleTextRotation = new UniverStyleTextRotation();
+        univerStyleTextRotation.setA(cellStyle.getRotation());
+        univerStyle.setTr(univerStyleTextRotation);
+        return univerStyle;
+    }
+
+    private String rgb(short[] color) {
+        String rgb = null;
+        if (null != color && color.length == 3) {
+            rgb = String.format("#%02X%02X%02X", color[0], color[1], color[2]);
+        }
+        return rgb;
+    }
+
+    private UniverStyleBorder getUniverStyleBorder(HSSFCellStyle cellStyle, HSSFWorkbook workbook) {
+        UniverStyleBorder univerStyleBorder = new UniverStyleBorder();
+        int num = 0;
+        HSSFPalette palette = workbook.getCustomPalette();
+        HSSFColor leftBorder = palette.getColor(cellStyle.getLeftBorderColor());
+        if (null != leftBorder) {
+            UniverStyleBorderStyle left = new UniverStyleBorderStyle();
+            UniverStyleColor leftColor = new UniverStyleColor();
+            leftColor.setRgb(rgb(leftBorder.getTriplet()));
+            left.setCl(leftColor);
+            univerStyleBorder.setL(left);
+            num++;
+        }
+        HSSFColor topBorder = palette.getColor(cellStyle.getTopBorderColor());
+        if (null != topBorder) {
+            UniverStyleBorderStyle top = new UniverStyleBorderStyle();
+            UniverStyleColor topColor = new UniverStyleColor();
+            topColor.setRgb(rgb(topBorder.getTriplet()));
+            top.setCl(topColor);
+            univerStyleBorder.setT(top);
+            num++;
+        }
+        HSSFColor rightBorder = palette.getColor(cellStyle.getRightBorderColor());
+        if (null != rightBorder) {
+            UniverStyleBorderStyle right = new UniverStyleBorderStyle();
+            UniverStyleColor rightColor = new UniverStyleColor();
+            rightColor.setRgb(rgb(rightBorder.getTriplet()));
+            right.setCl(rightColor);
+            univerStyleBorder.setR(right);
+            num++;
+        }
+        HSSFColor bottomBorder = palette.getColor(cellStyle.getBottomBorderColor());
+        if (null != bottomBorder) {
+            UniverStyleBorderStyle bottom = new UniverStyleBorderStyle();
+            UniverStyleColor bottomColor = new UniverStyleColor();
+            bottomColor.setRgb(rgb(bottomBorder.getTriplet()));
+            bottom.setCl(bottomColor);
+            univerStyleBorder.setB(bottom);
+            num++;
+        }
+        return num > 0 ? univerStyleBorder : null;
+    }
+
+    private List<UniverResource> getUniverResources(Map<String, String> resourceMap) {
+        List<UniverResource> resourcesList = new ArrayList<>();
+        for (ResourceEnum resource : ResourceEnum.values()) {
+            UniverResource model = new UniverResource();
+            String name = resource.name();
+            model.setName(name);
+            model.setData(resourceMap.get(name) != null ? resourceMap.get(name) : "{}");
+            resourcesList.add(model);
+        }
+        return resourcesList;
+    }
+
+    private void drawing(HSSFSheet sheet, String sheetId, String unitId, Map<String, UniverResourceData> drawingMap) {
+        List<String> order = new ArrayList<>();
+        Map<String, UniverDrawing> data = new HashMap<>();
+        HSSFPatriarch drawing = sheet.getDrawingPatriarch();
+        if (drawing != null) {
+            List<HSSFShape> shapes = drawing.getChildren();
+            for (HSSFShape shape : shapes) {
+                if (shape instanceof HSSFPicture) {
+                    HSSFPicture picture = (HSSFPicture) shape;
+                    byte[] pictureData = picture.getPictureData().getData();
+                    if (pictureData.length > 0) {
+                        String drawingId = RandomUtil.randomString(10);
+                        order.add(drawingId);
+                        BufferedImage image = ImgUtil.toImage(pictureData);
+                        UniverTransform sheetTransform = new UniverTransform();
+                        HSSFClientAnchor anchor = picture.getClientAnchor();
+                        UniverOffset univerFrom = new UniverOffset();
+                        univerFrom.setRow(anchor.getRow1());
+                        univerFrom.setColumn((int) anchor.getCol1());
+                        univerFrom.setRowOffset(0);
+                        univerFrom.setColumnOffset(0);
+                        sheetTransform.setFrom(univerFrom);
+                        UniverOffset univerTo = new UniverOffset();
+                        univerTo.setRow(anchor.getRow2());
+                        univerTo.setColumn((int) anchor.getCol2());
+                        univerTo.setRowOffset(0);
+                        univerTo.setColumnOffset(0);
+                        sheetTransform.setTo(univerTo);
+                        UniverDrawing univerDrawing = new UniverDrawing();
+                        univerDrawing.setSheetTransform(sheetTransform);
+                        UniverTransform transform = new UniverTransform();
+                        transform.setFlipX(false);
+                        transform.setFlipY(false);
+                        transform.setSkewX(0);
+                        transform.setSkewY(0);
+                        transform.setAngle(0);
+                        transform.setLeft(500);
+                        transform.setTop(500);
+                        transform.setHeight(500);
+                        transform.setWidth(500);
+                        univerDrawing.setTransform(transform);
+                        univerDrawing.setAllowTransform(true);
+                        univerDrawing.setDrawingType(0);
+                        univerDrawing.setUnitId(unitId);
+                        univerDrawing.setSubUnitId(sheetId);
+                        univerDrawing.setDrawingId(drawingId);
+                        univerDrawing.setImageSourceType(ImageEnum.BASE64.name());
+                        univerDrawing.setSource("data:image/jpeg;base64," + ImgUtil.toBase64(image, "jpeg"));
+                        data.put(drawingId, univerDrawing);
+                    }
+                }
+            }
+        }
+        if (!order.isEmpty()) {
+            UniverResourceData resourceData = new UniverResourceData();
+            resourceData.setData(data);
+            resourceData.setOrder(order);
+            drawingMap.put(sheetId, resourceData);
+        }
+    }
+
+    private void format(HSSFSheet sheet, String sheetId, String unitId, Map<String, List<UniverResourceData>> formattingMap) {
+        //todo 提供色阶、数据条、色阶方法,其他方法获取的数据有问题
+        List<UniverResourceData> formatList = new ArrayList<>();
+        HSSFSheetConditionalFormatting formatting = sheet.getSheetConditionalFormatting();
+        if (null != formatting) {
+            for (int i = 0; i < formatting.getNumConditionalFormattings(); i++) {
+                HSSFConditionalFormatting format = formatting.getConditionalFormattingAt(i);
+                UniverResourceData resourceData = new UniverResourceData();
+                resourceData.setCfId(RandomUtil.randomString(10));
+                CellRangeAddress[] formattingRanges = format.getFormattingRanges();
+                List<UniverSheetRange> ranges = new ArrayList<>();
+                resourceData.setRanges(ranges);
+                for (CellRangeAddress rangeAddress : formattingRanges) {
+                    UniverSheetRange range = new UniverSheetRange();
+                    range.setStartRow(rangeAddress.getFirstRow());
+                    range.setStartColumn(rangeAddress.getFirstColumn());
+                    range.setEndRow(rangeAddress.getLastRow());
+                    range.setEndColumn(rangeAddress.getLastColumn());
+                    range.setUnitId(unitId);
+                    range.setSheetId(sheetId);
+                    ranges.add(range);
+                }
+                for (int num = 0; num < format.getNumberOfRules(); num++) {
+                    HSSFConditionalFormattingRule formatRule = format.getRule(num);
+                    HSSFIconMultiStateFormatting iconSet = formatRule.getMultiStateFormatting();
+                    if (iconSet != null) {
+                        boolean reverse = iconSet.isReversed();
+                        UniverRule rule = new UniverRule();
+                        List<UniverConfig> univerConfig = new ArrayList<>();
+                        rule.setType(FormatTypeEnum.iconSet.name());
+                        rule.setConfig(univerConfig);
+                        //显示数据条没有属性
+                        rule.setIsShowValue(false);
+                        String iconType = iconSet.getIconSet().name;
+                        HSSFConditionalFormattingThreshold[] cfvoList = iconSet.getThresholds();
+                        int iconId = 0;
+                        for (int k = cfvoList.length - 1; k >= 0; k--) {
+                            HSSFConditionalFormattingThreshold cfvo = cfvoList[k];
+                            UniverValue value = new UniverValue();
+                            String type = cfvo.getRangeType().name;
+                            String val = Objects.equals(SubTypeEnum.expression.getCode(), type) ? "=" + cfvo.getFormula().replaceAll("\"", "") : cfvo.getValue() + "";
+                            value.setValue(val);
+                            value.setType(type);
+                            UniverConfig config = new UniverConfig();
+                            config.setOperator(OperatorEnum.greaterThan.name());
+                            config.setIconId((reverse ? k : iconId) + "");
+                            config.setIconType(iconType);
+                            config.setValue(value);
+                            univerConfig.add(config);
+                            iconId++;
+                        }
+                        resourceData.setRule(rule);
+                    }
+
+                    HSSFDataBarFormatting dataBar = formatRule.getDataBarFormatting();
+                    if (dataBar != null) {
+                        UniverRule rule = new UniverRule();
+                        UniverConfig config = new UniverConfig();
+                        rule.setConfig(config);
+                        rule.setType(FormatTypeEnum.dataBar.name());
+                        //显示数据条没有属性
+                        rule.setIsShowValue(false);
+                        HSSFConditionalFormattingThreshold minThreshold = dataBar.getMinThreshold();
+                        UniverValue min = new UniverValue();
+                        min.setType(minThreshold.getRangeType().name);
+                        min.setValue(Objects.equals(SubTypeEnum.expression.getCode(), min.getType()) ? "=" + minThreshold.getFormula().replaceAll("\"", "") : minThreshold.getValue() + "");
+                        config.setMin(min);
+                        HSSFConditionalFormattingThreshold maxThreshold = dataBar.getMaxThreshold();
+                        UniverValue max = new UniverValue();
+                        max.setType(maxThreshold.getRangeType().name);
+                        max.setValue(Objects.equals(SubTypeEnum.expression.getCode(), max.getType()) ? "=" + maxThreshold.getFormula().replaceAll("\"", "") : maxThreshold.getValue() + "");
+                        config.setMax(max);
+                        config.setIsGradient(true);
+                        resourceData.setRule(rule);
+                    }
+
+                    HSSFColorScaleFormatting colorScale = formatRule.getColorScaleFormatting();
+                    if (colorScale != null) {
+                        UniverRule rule = new UniverRule();
+                        List<UniverConfig> univerConfig = new ArrayList<>();
+                        rule.setType(FormatTypeEnum.colorScale.name());
+                        rule.setConfig(univerConfig);
+                        Map<Integer, UniverValue> colorValue = new HashMap<>();
+                        HSSFConditionalFormattingThreshold[] cfvoList = colorScale.getThresholds();
+                        for (int k = 0; k < cfvoList.length; k++) {
+                            HSSFConditionalFormattingThreshold cfvo = cfvoList[k];
+                            UniverValue value = new UniverValue();
+                            String type = cfvo.getRangeType().name;
+                            String val = Objects.equals(SubTypeEnum.expression.getCode(), type) ? "=" + cfvo.getFormula().replaceAll("\"", "") : cfvo.getValue() + "";
+                            value.setType(type);
+                            value.setValue(val);
+                            colorValue.put(k, value);
+                        }
+                        for (Integer k : colorValue.keySet()) {
+                            UniverConfig config = new UniverConfig();
+                            config.setValue(colorValue.get(k));
+                            config.setIndex(k);
+                            univerConfig.add(config);
+                        }
+                        resourceData.setRule(rule);
+                    }
+
+                    resourceData.setStopIfTrue(formatRule.getStopIfTrue());
+                    if (resourceData.getRule() == null) {
+                        continue;
+                    }
+                    formatList.add(resourceData);
+                }
+            }
+        }
+        formattingMap.put(sheetId, formatList);
+    }
+
+    private void filter(HSSFSheet sheet, String sheetId, String unitId, Map<String, UniverResourceData> filterMap) {
+        //todo 只有获取筛选的格子,没有提供筛选的内容
+        int sheetIndex = sheet.getWorkbook().getSheetIndex(sheet) + 1;
+        UniverResourceData data = new UniverResourceData();
+        InternalWorkbook workbook = sheet.getWorkbook().getWorkbook();
+        if (workbook != null) {
+            NameRecord name = workbook.getSpecificBuiltinRecord((byte) 13, sheetIndex);
+            if (name != null) {
+                Ptg[] nameDefinition = name.getNameDefinition();
+                String formulaString = HSSFFormulaParser.toFormulaString(sheet.getWorkbook(), nameDefinition);
+                CellRangeAddress addresses = CellRangeAddress.valueOf(formulaString);
+                UniverSheetRange ref = new UniverSheetRange();
+                ref.setStartRow(addresses.getFirstRow());
+                ref.setStartColumn(addresses.getFirstColumn());
+                ref.setEndRow(addresses.getLastRow());
+                ref.setEndColumn(addresses.getLastColumn());
+                data.setRef(ref);
+                List<UniverFilters> filterColumns = new ArrayList();
+                data.setFilterColumns(filterColumns);
+                List<Integer> cachedFilteredOut = new ArrayList<>();
+                data.setCachedFilteredOut(cachedFilteredOut);
+                filterMap.put(sheetId, data);
+            }
+        }
+    }
+
+    private static void dataValidation(HSSFSheet sheet, String sheetId, String unitId, Map<String, List<UniverResourceData>> dataValidationMap) {
+        List<UniverResourceData> dataValidationList = new ArrayList<>();
+        List<HSSFDataValidation> dataValidations = sheet.getDataValidations();
+        for (HSSFDataValidation dataValidation : dataValidations) {
+            UniverResourceData resourceData = new UniverResourceData();
+            List<UniverSheetRange> ranges = new ArrayList<>();
+            resourceData.setRanges(ranges);
+            resourceData.setUid(RandomUtil.randomString(10));
+            CellRangeAddressList addressList = dataValidation.getRegions();
+            for (CellRangeAddress address : addressList.getGenericChildren()) {
+                UniverSheetRange sheetRange = new UniverSheetRange();
+                sheetRange.setStartRow(address.getFirstRow());
+                sheetRange.setStartColumn(address.getFirstColumn());
+                sheetRange.setEndRow(address.getLastRow());
+                sheetRange.setEndColumn(address.getLastColumn());
+                sheetRange.setSheetId(sheetId);
+                sheetRange.setUnitId(unitId);
+                ranges.add(sheetRange);
+            }
+            DVConstraint constraint = (DVConstraint) dataValidation.getValidationConstraint();
+            ValidationType validationType = ValidationType.getType(constraint.getValidationType());
+            resourceData.setType(validationType.getType());
+            operatorTypeEnum operator = Objects.equals(validationType, ValidationType.none) ? null : operatorTypeEnum.getOperator(constraint.getOperator());
+            resourceData.setOperator(operator != null ? operator.getOperatorType() : null);
+            String value1 = constraint.getValue1() != null ? constraint.getValue1().toString() : constraint.getFormula1();
+            String value2 = constraint.getValue2() != null ? constraint.getValue2().toString() : constraint.getFormula2();
+            resourceData.setFormula1(value1 != null ? value1.replaceAll("\"", "") : value1);
+            resourceData.setFormula2(value2 != null ? value2.replaceAll("\"", "") : value2);
+            if (dataValidation.getShowErrorBox()) {
+                resourceData.setShowErrorMessage(true);
+                resourceData.setError(dataValidation.getErrorBoxTitle());
+                resourceData.setErrorStyle(Objects.equals(dataValidation.getErrorStyle(), 0) ? 1 : 2);
+            }
+            resourceData.setAllowBlank(dataValidation.getEmptyCellAllowed());
+            resourceData.setRenderMode(dataValidation.getSuppressDropDownArrow() ? null : 0);
+            dataValidationList.add(resourceData);
+        }
+        dataValidationMap.put(sheetId, dataValidationList);
+    }
+
+    private Map<String, UniverResourceData> definedName(HSSFWorkbook workbook, Map<String, String> definedName, Map<String, String> univerSheetMap) {
+        Map<String, UniverResourceData> definedNameMap = new HashMap<>();
+        for (HSSFName name : workbook.getAllNames()) {
+            String definedId = RandomUtil.randomString(10);
+            String localSheetId = "AllDefaultWorkbook";
+            String nameName = name.getNameName();
+            int sheetIndex = name.getSheetIndex();
+            String sheetName = "";
+            if (sheetIndex > -1) {
+                HSSFSheet sheetAt = workbook.getSheetAt(sheetIndex);
+                sheetName = sheetAt.getSheetName();
+                localSheetId = univerSheetMap.get(sheetName);
+            }
+            definedName.put(nameName + (StringUtil.isNotEmpty(sheetName) ? "!" + sheetName : ""), definedId);
+            UniverResourceData resourceData = new UniverResourceData();
+            resourceData.setId(definedId);
+            resourceData.setName(nameName);
+            resourceData.setFormulaOrRefString(name.getRefersToFormula());
+            resourceData.setComment(name.getComment());
+            resourceData.setLocalSheetId(localSheetId);
+            definedNameMap.put(definedId, resourceData);
+        }
+        return definedNameMap;
+    }
+
+    private void link(HSSFCell cell, Object value, Map<String, String> definedName, Map<String, String> univerSheetMap, UniverSheetCellData univerSheetCellData) {
+        Hyperlink link = cell.getHyperlink();
+        if (link != null) {
+            String address = link.getAddress();
+            if (StringUtil.isEmpty(address)) {
+                return;
+            }
+            //body
+            UniverBody body = new UniverBody();
+            String dataValue = value != null ? value.toString() : "";
+            if (StringUtil.isEmpty(dataValue)) {
+                return;
+            }
+            List<String> typeList = ImmutableList.of("\r\n", "\n", "\r");
+            for (String type : typeList) {
+                dataValue = StringUtils.removeEnd(dataValue, type);
+            }
+            int valueIndex = dataValue.length();
+            String dataStream = dataValue + "\r\n";
+            body.setDataStream(dataStream);
+            //customRanges
+            List<UniverBodyConfig> customRangesList = new ArrayList<>();
+            UniverBodyConfig customRanges = new UniverBodyConfig();
+            customRanges.setRangeId(RandomUtil.randomString(10));
+            customRanges.setRangeType(0);
+            customRanges.setStartIndex(0);
+            UniverBodyConfig properties = new UniverBodyConfig();
+            String[] split = address.split("!");
+            String url = Objects.equals(link.getType(), HyperlinkType.URL) ? address : definedName.get(address) != null ? "#rangeid=" + definedName.get(address) : "";
+            String linkSheetId = univerSheetMap.get(split[0]);
+            if (linkSheetId != null && split.length > 1) {
+                url = "#gid=" + linkSheetId + "&range=" + split[1];
+            }
+            properties.setUrl(url);
+            properties.setRefId(customRanges.getRangeId());
+            customRanges.setEndIndex(valueIndex > 0 ? valueIndex - 1 : valueIndex);
+            customRanges.setProperties(properties);
+            customRangesList.add(customRanges);
+            body.setCustomRanges(customRangesList);
+            //textRuns
+            body.setTextRuns(new ArrayList<>());
+            //customDecorations
+            body.setCustomDecorations(new ArrayList<>());
+            //sectionBreaks
+            List<UniverBodyConfig> sectionBreaksList = new ArrayList<>();
+            UniverBodyConfig sectionBreaks = new UniverBodyConfig();
+            sectionBreaks.setStartIndex(valueIndex + 1);
+            sectionBreaksList.add(sectionBreaks);
+            body.setSectionBreaks(sectionBreaksList);
+            //paragraphs
+            List<UniverBodyConfig> paragraphsList = new ArrayList<>();
+            UniverBodyConfig paragraphs = new UniverBodyConfig();
+            paragraphs.setStartIndex(valueIndex);
+            UniverBodyConfig paragraphStyle = new UniverBodyConfig();
+            paragraphStyle.setHorizontalAlign(0);
+            paragraphs.setParagraphStyle(paragraphStyle);
+            paragraphsList.add(paragraphs);
+            body.setParagraphs(paragraphsList);
+            UniverProperties p = new UniverProperties();
+            p.setBody(body);
+            p.setId("d");
+            univerSheetCellData.setP(p);
+            univerSheetCellData.setV(null);
+        }
+    }
+}

+ 846 - 0
jnpf-datareport-univer-common/src/main/java/jnpf/util/excel/UniverXSSFExcel.java

@@ -0,0 +1,846 @@
+package jnpf.util.excel;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.img.ImgUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.json.JSONUtil;
+import com.google.common.collect.ImmutableList;
+import jnpf.enums.*;
+import jnpf.univer.data.resource.*;
+import jnpf.univer.model.UniverWorkBook;
+import jnpf.univer.properties.UniverBody;
+import jnpf.univer.properties.UniverBodyConfig;
+import jnpf.univer.properties.UniverProperties;
+import jnpf.univer.resources.UniverResource;
+import jnpf.univer.resources.UniverResourceData;
+import jnpf.univer.sheet.*;
+import jnpf.univer.style.*;
+import jnpf.util.StringUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.common.usermodel.HyperlinkType;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.util.CellAddress;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.CellRangeAddressList;
+import org.apache.poi.ss.util.PaneInformation;
+import org.apache.poi.xssf.model.StylesTable;
+import org.apache.poi.xssf.usermodel.*;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
+
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/6/20 下午4:30
+ */
+public class UniverXSSFExcel extends ExcelParser {
+
+    @Override
+    public UniverWorkBook formFile(InputStream inputStream) throws IOException {
+        XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
+        UniverWorkBook univerWorkBook = new UniverWorkBook();
+        String unitId = RandomUtil.randomString(10);
+        univerWorkBook.setId(unitId);
+        univerWorkBook.setName("");
+        Map<UniverStyle, String> styleMap = new HashMap<>();
+        List<UniverSheet> sheetList = new ArrayList<>();
+        //sheet名称对应的id
+        Map<String, String> univerSheetMap = new HashMap<>();
+        for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
+            String sheetId = RandomUtil.randomString(10);
+            XSSFSheet sheet = workbook.getSheetAt(i);
+            univerSheetMap.put(sheet.getSheetName(), sheetId);
+        }
+        Map<String, String> definedName = new HashMap<>();
+        Map<String, UniverResourceData> definedNameMap = definedName(workbook, definedName, univerSheetMap);
+        for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
+            XSSFSheet sheet = workbook.getSheetAt(i);
+            String sheetName = sheet.getSheetName();
+            String sheetId = univerSheetMap.get(sheetName);
+            UniverSheet univerSheet = new UniverSheet();
+            univerSheet.setId(sheetId);
+            univerSheet.setName(sheetName);
+            univerSheet.setHidden(!workbook.isSheetHidden(i) ? 0 : 1);
+            univerSheet.setTabColor("");
+            //冻结位置
+            UniverSheetFreeze sheetFreeze = new UniverSheetFreeze();
+            PaneInformation freeze = sheet.getPaneInformation();
+            if (freeze != null) {
+                int freezeColumn = freeze.getVerticalSplitLeftColumn();
+                if (freezeColumn > 0) {
+                    sheetFreeze.setStartColumn(freezeColumn);
+                    sheetFreeze.setXSplit(freezeColumn);
+                }
+                int freezeRow = freeze.getHorizontalSplitTopRow();
+                if (freezeRow > 0) {
+                    sheetFreeze.setStartRow(freezeRow);
+                    sheetFreeze.setYSplit(freezeRow);
+                }
+            }
+            univerSheet.setFreeze(sheetFreeze);
+
+            Map<Integer, UniverSheetRowData> rowData = new HashMap<>();
+            Map<Integer, UniverSheetColumnData> columnData = new HashMap<>();
+            Map<Integer, Map<Integer, UniverSheetCellData>> cellData = new HashMap<>();
+            for (int rowCount = 0; rowCount <= sheet.getLastRowNum(); rowCount++) {
+                XSSFRow row = sheet.getRow(rowCount);
+                Map<Integer, UniverSheetCellData> cells = new HashMap<>();
+                if (null != row) {
+                    for (int columnCount = 0; columnCount <= row.getLastCellNum(); columnCount++) {
+                        XSSFCell cell = row.getCell(columnCount);
+                        UniverSheetCellData univerSheetCellData = new UniverSheetCellData();
+                        if (null != cell) {
+                            //数据
+                            Object value = "";
+                            String formula = null;
+                            CellType cellType = cell.getCellType();
+                            Integer type = null;
+                            switch (cellType) {
+                                case STRING:
+                                    value = cell.getStringCellValue();
+                                    type = CellDataTypeEnum.String.getCode();
+                                    break;
+                                case BOOLEAN:
+                                    value = cell.getBooleanCellValue();
+                                    type = CellDataTypeEnum.Boolean.getCode();
+                                    break;
+                                case NUMERIC:
+                                    value = new BigDecimal(cell.getNumericCellValue());
+                                    type = CellDataTypeEnum.Number.getCode();
+                                    break;
+                                case FORMULA:
+                                    value = cell.getCellFormula();
+                                    formula = "=" + value;
+                                    type = CellDataTypeEnum.Formula.getCode();
+                                    break;
+                            }
+                            univerSheetCellData.setV(value);
+                            univerSheetCellData.setF(formula);
+                            univerSheetCellData.setT(type);
+                            //样式
+                            XSSFCellStyle cellStyle = cell.getCellStyle();
+                            UniverStyle style = getUniverStyle(cellStyle);
+                            String styleName = styleMap.get(style) != null ? styleMap.get(style) : RandomUtil.randomString(6);
+                            styleMap.put(style, styleName);
+                            univerSheetCellData.setS(styleName);
+                            cells.put(columnCount, univerSheetCellData);
+                            UniverSheetColumnData univerSheetColumnData = new UniverSheetColumnData();
+                            univerSheetColumnData.setHd(!sheet.isColumnHidden(columnCount) ? 0 : 1);
+                            List<Integer> colHeight = new ArrayList<>();
+                            colHeight.add(100);
+                            colHeight.add((int) sheet.getColumnWidthInPixels(columnCount));
+                            univerSheetColumnData.setW(Collections.max(colHeight));
+                            columnData.put(columnCount, univerSheetColumnData);
+                            link(cell, value, definedName, univerSheetMap, univerSheetCellData);
+                        }
+                    }
+                    cellData.put(rowCount, cells);
+                    UniverSheetRowData univerSheetRowData = new UniverSheetRowData();
+                    univerSheetRowData.setHd(!row.getZeroHeight() ? 0 : 1);
+                    List<Integer> rowHeight = new ArrayList<>();
+                    rowHeight.add(50);
+                    rowHeight.add((int) row.getHeightInPoints());
+                    univerSheetRowData.setH(Collections.max(rowHeight));
+                    univerSheetRowData.setIa(0);
+                    rowData.put(rowCount, univerSheetRowData);
+                }
+            }
+            univerSheet.setCellData(cellData);
+            univerSheet.setRowData(rowData);
+            univerSheet.setColumnData(columnData);
+
+            List<UniverSheetRange> mergeData = new ArrayList<>();
+            for (CellRangeAddress region : sheet.getMergedRegions()) {
+                UniverSheetRange univerSheetRange = new UniverSheetRange();
+                univerSheetRange.setStartRow(region.getFirstRow());
+                univerSheetRange.setStartColumn(region.getFirstColumn());
+                univerSheetRange.setEndRow(region.getLastRow());
+                univerSheetRange.setEndColumn(region.getLastColumn());
+                mergeData.add(univerSheetRange);
+            }
+            univerSheet.setMergeData(mergeData);
+
+            UniverSheetRowHeader univerSheetRowHeader = new UniverSheetRowHeader();
+            univerSheetRowHeader.setHidden(0);
+            univerSheetRowHeader.setWidth(46);
+            univerSheet.setRowHeader(univerSheetRowHeader);
+
+            UniverSheetColumnHeader univerSheetColumnHeader = new UniverSheetColumnHeader();
+            univerSheetColumnHeader.setHidden(0);
+            univerSheetColumnHeader.setHeight(20);
+            univerSheet.setColumnHeader(univerSheetColumnHeader);
+
+            univerSheet.setZoomRatio(1);
+            univerSheet.setScrollTop(0);
+            univerSheet.setScrollLeft(0);
+            univerSheet.setDefaultColumnWidth(88);
+            univerSheet.setDefaultRowHeight(24);
+            List<Integer> rowCount = new ArrayList<>();
+            rowCount.add(100);
+            rowCount.add(rowData.size());
+            univerSheet.setRowCount(Collections.max(rowCount));
+            List<Integer> columnCount = new ArrayList<>();
+            columnCount.add(30);
+            columnCount.add(columnData.size());
+            univerSheet.setColumnCount(Collections.max(columnCount));
+            univerSheet.setShowGridlines(sheet.isDisplayGridlines() ? 1 : 0);
+
+            univerSheet.setSelections(ImmutableList.of("A1"));
+            univerSheet.setRightToLeft(0);
+            sheetList.add(univerSheet);
+        }
+
+        Map<String, UniverStyle> styles = styleMap.entrySet().stream().collect(Collectors.toMap(t -> t.getValue(), t -> t.getKey()));
+        univerWorkBook.setStyles(styles);
+        Map<String, UniverSheet> sheetMap = sheetList.stream().collect(Collectors.toMap(UniverSheet::getId, Function.identity(), (s1, s2) -> s1, LinkedHashMap::new));
+        univerWorkBook.setSheetOrder(new ArrayList<>(sheetMap.keySet()));
+        univerWorkBook.setSheets(sheetMap);
+
+        //图片
+        Map<String, UniverResourceData> drawingMap = new HashMap<>();
+        //条件
+        Map<String, List<UniverResourceData>> formattingMap = new HashMap<>();
+        //数据管理
+        Map<String, List<UniverResourceData>> dataValidationMap = new HashMap<>();
+        //筛选
+        Map<String, UniverResourceData> filterMap = new HashMap<>();
+        //处理前端要的数据格式
+        univerSheetMap.forEach((key, value) -> {
+            XSSFSheet sheet = workbook.getSheet(key);
+            if (sheet != null) {
+                //图片
+                drawing(sheet, value, unitId, drawingMap);
+                //条件
+                format(sheet, value, unitId, formattingMap);
+                //数据管理
+                dataValidation(sheet, value, unitId, dataValidationMap);
+                //筛选
+                filter(sheet, value, unitId, filterMap);
+            }
+        });
+        Map<String, String> resourceMap = new HashMap<>();
+        resourceMap.put(ResourceEnum.SHEET_DRAWING_PLUGIN.name(), JSONUtil.toJsonStr(drawingMap));
+        resourceMap.put(ResourceEnum.SHEET_CONDITIONAL_FORMATTING_PLUGIN.name(), JSONUtil.toJsonStr(formattingMap));
+        resourceMap.put(ResourceEnum.SHEET_DATA_VALIDATION_PLUGIN.name(), JSONUtil.toJsonStr(dataValidationMap));
+        resourceMap.put(ResourceEnum.SHEET_FILTER_PLUGIN.name(), JSONUtil.toJsonStr(filterMap));
+//        resourceMap.put(ResourceEnum.SHEET_DEFINED_NAME_PLUGIN.name(), JSONUtil.toJsonStr(definedNameMap));
+        univerWorkBook.setResources(getUniverResources(resourceMap));
+        return univerWorkBook;
+    }
+
+    private UniverStyle getUniverStyle(XSSFCellStyle cellStyle) {
+        UniverStyle univerStyle = new UniverStyle();
+        univerStyle.setHt(HorizontalEnum.getHorizontalCode(cellStyle.getAlignment()));
+        univerStyle.setVt(VerticalEnum.getVerticalCode(cellStyle.getVerticalAlignment()));
+
+        XSSFFont font = cellStyle.getFont();
+        if (null != font) {
+            univerStyle.setFf(font.getFontName());
+            univerStyle.setFs((int) font.getFontHeightInPoints());
+            univerStyle.setIt(font.getItalic() ? 1 : 0);
+            univerStyle.setBl(font.getBold() ? 1 : 0);
+            XSSFColor color = font.getXSSFColor();
+            if (null != color) {
+                UniverStyleColor cl = new UniverStyleColor();
+                cl.setRgb(rgb(color.getARGBHex()));
+                univerStyle.setCl(cl);
+            }
+            if (Objects.equals(font.getUnderline(), Font.U_SINGLE)) {
+                UniverStyleTextDecoration ul = new UniverStyleTextDecoration();
+                ul.setS(1);
+                univerStyle.setUl(ul);
+            }
+            if (font.getStrikeout()) {
+                UniverStyleTextDecoration st = new UniverStyleTextDecoration();
+                st.setS(1);
+                univerStyle.setSt(st);
+            }
+        }
+        if (null != cellStyle.getDataFormatString()) {
+            UniverStylePattern pattern = new UniverStylePattern();
+            pattern.setPattern(cellStyle.getDataFormatString());
+            univerStyle.setN(pattern);
+        }
+        univerStyle.setBd(getUniverStyleBorder(cellStyle));
+
+        XSSFColor bgColor = cellStyle.getFillForegroundColorColor();
+        FillPatternType pattern = cellStyle.getFillPattern();
+        if (null != bgColor && Objects.equals(pattern, FillPatternType.SOLID_FOREGROUND)) {
+            UniverStyleColor background = new UniverStyleColor();
+            background.setRgb(rgb(bgColor.getARGBHex()));
+            univerStyle.setBg(background);
+        }
+
+        UniverStyleTextRotation univerStyleTextRotation = new UniverStyleTextRotation();
+        univerStyleTextRotation.setA(cellStyle.getRotation());
+        univerStyle.setTr(univerStyleTextRotation);
+        return univerStyle;
+    }
+
+    private String rgb(String color) {
+        String rgb = null;
+        if (StringUtil.isNotEmpty(color)) {
+            rgb = "#" + color.substring(2, 8);
+        }
+        return rgb;
+    }
+
+    private UniverStyleBorder getUniverStyleBorder(XSSFCellStyle cellStyle) {
+        UniverStyleBorder univerStyleBorder = new UniverStyleBorder();
+        int num = 0;
+        XSSFColor leftBorder = cellStyle.getLeftBorderXSSFColor();
+        if (null != leftBorder) {
+            UniverStyleBorderStyle left = new UniverStyleBorderStyle();
+            UniverStyleColor leftColor = new UniverStyleColor();
+            leftColor.setRgb(rgb(leftBorder.getARGBHex()));
+            left.setCl(leftColor);
+            univerStyleBorder.setL(left);
+            num++;
+        }
+        XSSFColor topBorder = cellStyle.getTopBorderXSSFColor();
+        if (null != topBorder) {
+            UniverStyleBorderStyle top = new UniverStyleBorderStyle();
+            UniverStyleColor topColor = new UniverStyleColor();
+            topColor.setRgb(rgb(topBorder.getARGBHex()));
+            top.setCl(topColor);
+            univerStyleBorder.setT(top);
+            num++;
+        }
+        XSSFColor rightBorder = cellStyle.getRightBorderXSSFColor();
+        if (null != rightBorder) {
+            UniverStyleBorderStyle right = new UniverStyleBorderStyle();
+            UniverStyleColor rightColor = new UniverStyleColor();
+            rightColor.setRgb(rgb(rightBorder.getARGBHex()));
+            right.setCl(rightColor);
+            univerStyleBorder.setR(right);
+            num++;
+        }
+        XSSFColor bottomBorder = cellStyle.getBottomBorderXSSFColor();
+        if (null != bottomBorder) {
+            UniverStyleBorderStyle bottom = new UniverStyleBorderStyle();
+            UniverStyleColor bottomColor = new UniverStyleColor();
+            bottomColor.setRgb(rgb(bottomBorder.getARGBHex()));
+            bottom.setCl(bottomColor);
+            univerStyleBorder.setB(bottom);
+            num++;
+        }
+        return num > 0 ? univerStyleBorder : null;
+    }
+
+    private List<UniverResource> getUniverResources(Map<String, String> resourceMap) {
+        List<UniverResource> resourcesList = new ArrayList<>();
+        for (ResourceEnum resource : ResourceEnum.values()) {
+            UniverResource model = new UniverResource();
+            String name = resource.name();
+            model.setName(name);
+            model.setData(resourceMap.get(name) != null ? resourceMap.get(name) : "{}");
+            resourcesList.add(model);
+        }
+        return resourcesList;
+    }
+
+    private void drawing(XSSFSheet sheet, String sheetId, String unitId, Map<String, UniverResourceData> drawingMap) {
+        List<String> order = new ArrayList<>();
+        Map<String, UniverDrawing> data = new HashMap<>();
+        XSSFDrawing drawing = sheet.getDrawingPatriarch();
+        if (drawing != null) {
+            List<XSSFShape> shapes = drawing.getShapes();
+            for (XSSFShape shape : shapes) {
+                if (shape instanceof XSSFPicture) {
+                    XSSFPicture picture = (XSSFPicture) shape;
+                    byte[] pictureData = picture.getPictureData().getData();
+                    if (pictureData.length > 0) {
+                        String drawingId = RandomUtil.randomString(10);
+                        order.add(drawingId);
+                        BufferedImage image = ImgUtil.toImage(pictureData);
+                        UniverTransform sheetTransform = new UniverTransform();
+
+                        XSSFClientAnchor anchor = picture.getClientAnchor();
+                        UniverOffset univerFrom = new UniverOffset();
+                        univerFrom.setRowOffset(0);
+                        univerFrom.setColumnOffset(0);
+                        univerFrom.setRow(anchor.getRow1());
+                        univerFrom.setColumn((int) anchor.getCol1());
+                        sheetTransform.setFrom(univerFrom);
+                        UniverOffset univerTo = new UniverOffset();
+                        univerTo.setRowOffset(0);
+                        univerTo.setColumnOffset(0);
+                        univerTo.setRow(anchor.getRow2());
+                        univerTo.setColumn((int) anchor.getCol2());
+                        sheetTransform.setTo(univerTo);
+                        UniverDrawing univerDrawing = new UniverDrawing();
+                        univerDrawing.setSheetTransform(sheetTransform);
+                        UniverTransform transform = new UniverTransform();
+                        transform.setFlipX(false);
+                        transform.setFlipY(false);
+                        transform.setSkewX(0);
+                        transform.setSkewY(0);
+                        transform.setAngle(0);
+                        transform.setLeft(500);
+                        transform.setTop(500);
+                        transform.setHeight(500);
+                        transform.setWidth(500);
+                        univerDrawing.setTransform(transform);
+                        univerDrawing.setAllowTransform(true);
+                        univerDrawing.setDrawingType(0);
+                        univerDrawing.setUnitId(unitId);
+                        univerDrawing.setSubUnitId(sheetId);
+                        univerDrawing.setDrawingId(drawingId);
+                        univerDrawing.setImageSourceType(ImageEnum.BASE64.name());
+                        univerDrawing.setSource("data:image/jpeg;base64," + ImgUtil.toBase64(image, "jpeg"));
+                        data.put(drawingId, univerDrawing);
+                    }
+                }
+            }
+        }
+        if (!order.isEmpty()) {
+            UniverResourceData resourceData = new UniverResourceData();
+            resourceData.setData(data);
+            resourceData.setOrder(order);
+            drawingMap.put(sheetId, resourceData);
+        }
+    }
+
+    private void format(XSSFSheet sheet, String sheetId, String unitId, Map<String, List<UniverResourceData>> formattingMap) {
+        StylesTable styles = sheet.getWorkbook().getStylesSource();
+        List<UniverResourceData> formatList = new ArrayList<>();
+        List<CTConditionalFormatting> conditionalFormatting = sheet.getCTWorksheet().getConditionalFormattingList();
+        for (CTConditionalFormatting conditional : conditionalFormatting) {
+            UniverResourceData resourceData = new UniverResourceData();
+            resourceData.setCfId(RandomUtil.randomString(10));
+            List<UniverSheetRange> ranges = new ArrayList<>();
+            resourceData.setRanges(ranges);
+            List<String> formattingRanges = conditional.getSqref();
+            for (String range : formattingRanges) {
+                UniverSheetRange sheetRange = new UniverSheetRange();
+                CellRangeAddress rangeAddress = CellRangeAddress.valueOf(range);
+                sheetRange.setStartRow(rangeAddress.getFirstRow());
+                sheetRange.setStartColumn(rangeAddress.getFirstColumn());
+                sheetRange.setEndRow(rangeAddress.getLastRow());
+                sheetRange.setEndColumn(rangeAddress.getLastColumn());
+                sheetRange.setUnitId(unitId);
+                sheetRange.setSheetId(sheetId);
+                ranges.add(sheetRange);
+            }
+            List<CTCfRule> cfRuleList = conditional.getCfRuleList();
+            for (CTCfRule cfRule : cfRuleList) {
+                CTIconSet iconSet = cfRule.getIconSet();
+                if (iconSet != null) {
+                    boolean reverse = iconSet.getReverse();
+                    UniverRule rule = new UniverRule();
+                    List<UniverConfig> univerConfig = new ArrayList<>();
+                    rule.setType(FormatTypeEnum.iconSet.name());
+                    rule.setConfig(univerConfig);
+                    rule.setIsShowValue(iconSet.getShowValue());
+                    String iconType = iconSet.getIconSet().toString();
+                    List<CTCfvo> cfvoList = iconSet.getCfvoList();
+                    int iconId = 0;
+                    for (int k = cfvoList.size() - 1; k >= 0; k--) {
+                        CTCfvo cfvo = cfvoList.get(k);
+                        UniverValue value = new UniverValue();
+                        String type = cfvo.getType().toString();
+                        String cfValue = cfvo.getVal() != null ? cfvo.getVal().toString() : "";
+                        String val = (Objects.equals(SubTypeEnum.expression.getType(), type) ? "=" : "") + cfValue.replaceAll("\"", "");
+                        value.setValue(val);
+                        value.setType(type);
+                        UniverConfig config = new UniverConfig();
+                        config.setOperator(cfvo.getGte() ? OperatorEnum.greaterThanOrEqual.name() : OperatorEnum.greaterThan.name());
+                        config.setIconId((reverse ? k : iconId) + "");
+                        config.setIconType(iconType);
+                        config.setValue(value);
+                        univerConfig.add(config);
+                        iconId++;
+                    }
+                    resourceData.setRule(rule);
+                }
+                CTDataBar dataBar = cfRule.getDataBar();
+                if (dataBar != null) {
+                    UniverRule rule = new UniverRule();
+                    UniverConfig config = new UniverConfig();
+                    rule.setConfig(config);
+                    rule.setType(FormatTypeEnum.dataBar.name());
+                    rule.setIsShowValue(dataBar.getShowValue());
+                    List<CTCfvo> cfvoList = dataBar.getCfvoList();
+                    UniverValue min = new UniverValue();
+                    min.setType(OperatorEnum.min.name());
+                    config.setMin(min);
+                    UniverValue max = new UniverValue();
+                    max.setType(OperatorEnum.max.name());
+                    config.setMax(max);
+                    for (int k = 0; k < cfvoList.size(); k++) {
+                        CTCfvo cfvo = cfvoList.get(k);
+                        String type = cfvo.getType().toString();
+                        String cfValue = cfvo.getVal() != null ? cfvo.getVal().toString() : "";
+                        String val = (Objects.equals(SubTypeEnum.expression.getType(), type) ? "=" : "") + cfValue.replaceAll("\"", "");
+                        if (k == 0) {
+                            min.setValue(val);
+                            min.setType(type);
+                        } else {
+                            max.setValue(val);
+                            max.setType(Objects.equals(type, OperatorEnum.min.name()) ? max.getType() : type);
+                        }
+                    }
+                    config.setIsGradient(false);
+                    CTColor ctColor = dataBar.getColor();
+                    if (ctColor != null) {
+                        XSSFColor color = new XSSFColor(ctColor.getRgb());
+                        String colorRgb = rgb(color.getARGBHex());
+                        config.setPositiveColor(colorRgb);
+                        config.setNativeColor(colorRgb);
+                    }
+                    resourceData.setRule(rule);
+                }
+                CTColorScale colorScale = cfRule.getColorScale();
+                if (colorScale != null) {
+                    UniverRule rule = new UniverRule();
+                    List<UniverConfig> univerConfig = new ArrayList<>();
+                    rule.setType(FormatTypeEnum.colorScale.name());
+                    rule.setConfig(univerConfig);
+                    Map<Integer, UniverValue> colorValue = new HashMap<>();
+                    List<CTCfvo> cfvoList = colorScale.getCfvoList();
+                    for (int k = 0; k < cfvoList.size(); k++) {
+                        CTCfvo cfvo = cfvoList.get(k);
+                        UniverValue value = new UniverValue();
+                        String type = cfvo.getType().toString();
+                        String cfValue = cfvo.getVal() != null ? cfvo.getVal().toString() : "";
+                        String val = (Objects.equals(SubTypeEnum.expression.getType(), type) ? "=" : "") + cfValue.replaceAll("\"", "");
+                        value.setType(type);
+                        value.setValue(val);
+                        colorValue.put(k, value);
+                    }
+                    List<CTColor> colorList = colorScale.getColorList();
+                    Map<Integer, String> colorColor = new HashMap<>();
+                    for (int k = 0; k < colorList.size(); k++) {
+                        CTColor ctColor = colorList.get(k);
+                        XSSFColor color = new XSSFColor(ctColor.getRgb());
+                        String colorRgb = rgb(color.getARGBHex());
+                        colorColor.put(k, colorRgb);
+                    }
+                    for (Integer k : colorValue.keySet()) {
+                        UniverConfig config = new UniverConfig();
+                        config.setValue(colorValue.get(k));
+                        config.setColor(colorColor.get(k));
+                        config.setIndex(k);
+                        univerConfig.add(config);
+                    }
+                    resourceData.setRule(rule);
+                }
+                CTCfRule highlightCell = cfRule;
+                if (highlightCell != null) {
+                    String type = highlightCell.getType().toString();
+                    SubTypeEnum subTypeEnum = SubTypeEnum.getType(type);
+                    if (subTypeEnum != null) {
+                        UniverRule rule = new UniverRule();
+                        rule.setType(FormatTypeEnum.highlightCell.name());
+                        boolean isUnique = ImmutableList.of(SubTypeEnum.uniqueValues.getType(), SubTypeEnum.duplicateValues.getType()).contains(subTypeEnum.getType());
+                        boolean isNumber = Objects.equals(SubTypeEnum.cellIs.getType(), subTypeEnum.getType());
+                        boolean isAverage = Objects.equals(SubTypeEnum.aboveAverage.getType(), subTypeEnum.getType());
+                        boolean isRank = Objects.equals(SubTypeEnum.top10.getType(), subTypeEnum.getType());
+                        boolean isFormula = Objects.equals(SubTypeEnum.expression.getType(), subTypeEnum.getType());
+                        boolean isTime = Objects.equals(SubTypeEnum.timePeriod.getType(), subTypeEnum.getType());
+                        List<String> dataList = highlightCell.getFormulaList() != null ? highlightCell.getFormulaList() : new ArrayList<>();
+                        List<BigDecimal> numberDataList = new ArrayList<>();
+                        BigDecimal numberData = null;
+                        String textValue = "";
+                        for (String data : dataList) {
+                            try {
+                                BigDecimal bigDecimal = new BigDecimal(data);
+                                numberDataList.add(bigDecimal);
+                                numberData = bigDecimal;
+                            } catch (Exception e) {
+                                textValue = data;
+                            }
+                        }
+                        if (isNumber) {
+                            if (highlightCell.getOperator() != null) {
+                                rule.setOperator(highlightCell.getOperator().toString());
+                            }
+                            boolean isText = numberDataList.isEmpty();
+                            rule.setSubType(isText ? SubTypeEnum.text.getCode() : SubTypeEnum.cellIs.getCode());
+                            rule.setValue(isText ? textValue : numberDataList.size() > 1 ? numberDataList : numberData);
+                        } else if (isAverage) {
+                            rule.setSubType(subTypeEnum.getCode());
+                            rule.setOperator(highlightCell.getAboveAverage() ? OperatorEnum.greaterThan.name() : OperatorEnum.lessThan.name());
+                        } else if (isRank) {
+                            rule.setSubType(subTypeEnum.getCode());
+                            rule.setIsPercent(highlightCell.getPercent());
+                            rule.setIsBottom(highlightCell.getBottom());
+                            rule.setValue(highlightCell.getRank() + "");
+                        } else if (isFormula) {
+                            rule.setSubType(SubTypeEnum.expression.getCode());
+                            rule.setValue("=" + textValue.replaceAll("\"", ""));
+                        } else if (isTime) {
+                            rule.setSubType(subTypeEnum.getCode());
+                            rule.setOperator(highlightCell.getTimePeriod().toString());
+                        } else if (isUnique) {
+                            rule.setSubType(subTypeEnum.getType());
+                        } else {
+                            rule.setSubType(SubTypeEnum.text.getCode());
+                            rule.setOperator(highlightCell.getOperator() != null ? highlightCell.getOperator().toString() : subTypeEnum.getType());
+                            if (highlightCell.getText() != null) {
+                                rule.setValue(highlightCell.getText());
+                            }
+                        }
+                        UniverStyle style = new UniverStyle();
+                        CTDxf dxf = highlightCell.isSetDxfId() ? styles.getDxfAt((int) highlightCell.getDxfId()) : null;
+                        if (dxf != null) {
+                            CTFill ctFill = dxf.getFill();
+                            if (ctFill != null) {
+                                CTPatternFill patternFill = ctFill.getPatternFill();
+                                if (patternFill != null) {
+                                    XSSFColor baColor = XSSFColor.from(patternFill.getBgColor());
+                                    if (baColor != null) {
+                                        UniverStyleColor bg = new UniverStyleColor();
+                                        bg.setRgb(rgb(baColor.getARGBHex()));
+                                        style.setBg(bg);
+                                    }
+                                }
+                            }
+                            CTFont ctFont = dxf.getFont();
+                            if (ctFont != null) {
+                                XSSFColor fontColor = ctFont.sizeOfColorArray() > 0 ? XSSFColor.from(ctFont.getColorArray(0)) : null;
+                                if (fontColor != null) {
+                                    UniverStyleColor cl = new UniverStyleColor();
+                                    cl.setRgb(rgb(fontColor.getARGBHex()));
+                                    style.setCl(cl);
+                                }
+                                STUnderlineValues.Enum underlineType = ctFont.sizeOfUArray() == 1 ? ctFont.getUArray(0).getVal() : STUnderlineValues.NONE;
+                                if (Objects.equals(underlineType, STUnderlineValues.SINGLE)) {
+                                    UniverStyleTextDecoration ul = new UniverStyleTextDecoration();
+                                    ul.setS(1);
+                                    style.setUl(ul);
+                                }
+                                boolean strike = ctFont.sizeOfStrikeArray() > 0 && ctFont.getStrikeArray(0).getVal();
+                                if (strike) {
+                                    UniverStyleTextDecoration st = new UniverStyleTextDecoration();
+                                    st.setS(1);
+                                    style.setSt(st);
+                                }
+                                boolean isItalic = ctFont.sizeOfIArray() == 1 && ctFont.getIArray(0).getVal();
+                                boolean isBold = ctFont.sizeOfBArray() == 1 && ctFont.getBArray(0).getVal();
+                                style.setIt(isItalic ? 1 : 0);
+                                style.setBl(isBold ? 1 : 0);
+                            }
+                        }
+                        rule.setStyle(style);
+                        resourceData.setRule(rule);
+                    }
+                }
+                resourceData.setStopIfTrue(cfRule.getStopIfTrue());
+                if (resourceData.getRule() == null) {
+                    continue;
+                }
+                formatList.add(resourceData);
+            }
+        }
+        formattingMap.put(sheetId, formatList);
+    }
+
+    private static void dataValidation(XSSFSheet sheet, String sheetId, String unitId, Map<String, List<UniverResourceData>> dataValidationMap) {
+        List<UniverResourceData> dataValidationList = new ArrayList<>();
+        List<XSSFDataValidation> dataValidations = sheet.getDataValidations();
+        for (XSSFDataValidation dataValidation : dataValidations) {
+            UniverResourceData resourceData = new UniverResourceData();
+            List<UniverSheetRange> ranges = new ArrayList<>();
+            resourceData.setRanges(ranges);
+            resourceData.setUid(RandomUtil.randomString(10));
+            CellRangeAddressList addressList = dataValidation.getRegions();
+            for (CellRangeAddress address : addressList.getGenericChildren()) {
+                UniverSheetRange sheetRange = new UniverSheetRange();
+                sheetRange.setStartRow(address.getFirstRow());
+                sheetRange.setStartColumn(address.getFirstColumn());
+                sheetRange.setEndRow(address.getLastRow());
+                sheetRange.setEndColumn(address.getLastColumn());
+                sheetRange.setSheetId(sheetId);
+                sheetRange.setUnitId(unitId);
+                ranges.add(sheetRange);
+            }
+            DataValidationConstraint constraint = dataValidation.getValidationConstraint();
+            ValidationType validationType = ValidationType.getType(constraint.getValidationType());
+            resourceData.setType(validationType.getType());
+            operatorTypeEnum operator = Objects.equals(validationType, ValidationType.none) ? null : operatorTypeEnum.getOperator(constraint.getOperator());
+            resourceData.setOperator(operator != null ? operator.getOperatorType() : null);
+            String value1 = constraint.getFormula1();
+            String value2 = constraint.getFormula2();
+            resourceData.setFormula1(value1 != null ? value1.replaceAll("\"", "") : value1);
+            resourceData.setFormula2(value2 != null ? value2.replaceAll("\"", "") : value2);
+            if (dataValidation.getShowErrorBox()) {
+                resourceData.setShowErrorMessage(true);
+                resourceData.setError(dataValidation.getErrorBoxTitle());
+                resourceData.setErrorStyle(Objects.equals(dataValidation.getErrorStyle(), 0) ? 1 : 2);
+            }
+            resourceData.setAllowBlank(dataValidation.getEmptyCellAllowed());
+            resourceData.setRenderMode(dataValidation.getSuppressDropDownArrow() ? null : 0);
+            dataValidationList.add(resourceData);
+        }
+        dataValidationMap.put(sheetId, dataValidationList);
+    }
+
+    private void filter(XSSFSheet sheet, String sheetId, String unitId, Map<String, UniverResourceData> filterMap) {
+        CTAutoFilter autoFilter = sheet.getCTWorksheet().getAutoFilter();
+        UniverResourceData data = new UniverResourceData();
+        if (autoFilter != null && StringUtil.isNotEmpty(autoFilter.getRef())) {
+            CellRangeAddress addresses = CellRangeAddress.valueOf(autoFilter.getRef());
+            UniverSheetRange ref = new UniverSheetRange();
+            ref.setStartRow(addresses.getFirstRow());
+            ref.setStartColumn(addresses.getFirstColumn());
+            ref.setEndRow(addresses.getLastRow());
+            ref.setEndColumn(addresses.getLastColumn());
+            data.setRef(ref);
+            List<Integer> cachedFilteredOut = new ArrayList<>();
+            //隐藏行
+            for (int rowIndex = addresses.getFirstRow(); rowIndex <= addresses.getLastRow(); rowIndex++) {
+                XSSFRow row = sheet.getRow(rowIndex);
+                if (row != null && row.getZeroHeight()) {
+                    cachedFilteredOut.add(rowIndex);
+                }
+            }
+            //筛选条件
+            List<CTFilterColumn> filterColumnList = autoFilter.getFilterColumnList();
+            List<UniverFilters> filterColumns = new ArrayList<>();
+            for (CTFilterColumn filterColumn : filterColumnList) {
+                UniverFilters univerFilters = new UniverFilters();
+                univerFilters.setColId(filterColumn.getColId());
+
+                //poi方法
+                CTFilters ctFilters = filterColumn.getFilters();
+                if (BeanUtil.isNotEmpty(ctFilters)) {
+                    UniverCustomFilters univerCustomFilters = new UniverCustomFilters();
+                    univerFilters.setFilters(univerCustomFilters);
+                    univerCustomFilters.setAnd(ctFilters.getBlank() ? 1 : null);
+                    List<CTFilter> filtersFilterList = ctFilters.getFilterList();
+                    for (CTFilter ctFilter : filtersFilterList) {
+                        String val = ctFilter.getVal();
+                        ArrayList<String> strings = new ArrayList<>();
+                        strings.add(val);
+                        univerCustomFilters.setFilters(strings);
+                    }
+                    filterColumns.add(univerFilters);
+
+                }
+
+                CTCustomFilters filters = filterColumn.getCustomFilters();
+                if (null != filters) {
+                    UniverCustomFilters customFilters = new UniverCustomFilters();
+
+                    univerFilters.setCustomFilters(customFilters);
+
+                    List<UniverCustomFilters> customFilterList = new ArrayList<>();
+                    customFilters.setCustomFilters(customFilterList);
+                    customFilters.setAnd(filters.getAnd() ? 1 : null);
+                    List<CTCustomFilter> filterList = filters.getCustomFilterList();
+                    for (CTCustomFilter filter : filterList) {
+                        UniverCustomFilters univerCustomFilter = new UniverCustomFilters();
+                        univerCustomFilter.setVal(filter.getVal());
+//                        univerCustomFilter.setOperator(filter.getOperator() != null ? filter.getOperator().toString() : null);
+                        customFilterList.add(univerCustomFilter);
+                    }
+                    filterColumns.add(univerFilters);
+                }
+            }
+            data.setFilterColumns(filterColumns);
+            data.setCachedFilteredOut(cachedFilteredOut);
+            filterMap.put(sheetId, data);
+        }
+    }
+
+    private Map<String, UniverResourceData> definedName(XSSFWorkbook workbook, Map<String, String> definedName, Map<String, String> univerSheetMap) {
+        Map<String, UniverResourceData> definedNameMap = new HashMap<>();
+        for (XSSFName name : workbook.getAllNames()) {
+            String definedId = RandomUtil.randomString(10);
+            String localSheetId = "AllDefaultWorkbook";
+            String nameName = name.getNameName();
+            int sheetIndex = name.getSheetIndex();
+            String sheetName = "";
+            if (sheetIndex > -1) {
+                XSSFSheet sheetAt = workbook.getSheetAt(sheetIndex);
+                sheetName = sheetAt.getSheetName();
+                localSheetId = univerSheetMap.get(sheetName);
+            }
+            definedName.put(nameName + (StringUtil.isNotEmpty(sheetName) ? "!" + sheetName : ""), definedId);
+            UniverResourceData resourceData = new UniverResourceData();
+            resourceData.setId(definedId);
+            resourceData.setName(nameName);
+            resourceData.setFormulaOrRefString(name.getRefersToFormula());
+            resourceData.setComment(name.getComment());
+            resourceData.setLocalSheetId(localSheetId);
+            definedNameMap.put(definedId, resourceData);
+        }
+        return definedNameMap;
+    }
+
+    private void link(XSSFCell cell, Object value, Map<String, String> definedName, Map<String, String> univerSheetMap, UniverSheetCellData univerSheetCellData) {
+        Hyperlink link = cell.getHyperlink();
+        if (link != null) {
+            String address = link.getAddress();
+            if (StringUtil.isEmpty(address)) {
+                return;
+            }
+            //body
+            UniverBody body = new UniverBody();
+            String dataValue = value != null ? value.toString() : "";
+            if (StringUtil.isEmpty(dataValue)) {
+                return;
+            }
+            List<String> typeList = ImmutableList.of("\r\n", "\n", "\r");
+            for (String type : typeList) {
+                dataValue = StringUtils.removeEnd(dataValue, type);
+            }
+            int valueIndex = dataValue.length();
+            String dataStream = dataValue + "\r\n";
+            body.setDataStream(dataStream);
+            //customRanges
+            List<UniverBodyConfig> customRangesList = new ArrayList<>();
+            UniverBodyConfig customRanges = new UniverBodyConfig();
+            customRanges.setRangeId(RandomUtil.randomString(10));
+            customRanges.setRangeType(0);
+            customRanges.setStartIndex(0);
+            UniverBodyConfig properties = new UniverBodyConfig();
+            String[] split = address.split("!");
+            String url = Objects.equals(link.getType(), HyperlinkType.URL) ? address : definedName.get(address) != null ? "#rangeid=" + definedName.get(address) : "";
+            String linkSheetId = univerSheetMap.get(split[0]);
+            if (linkSheetId != null && split.length > 1) {
+                url = "#gid=" + linkSheetId + "&range=" + split[1];
+            }
+            properties.setUrl(url);
+            properties.setRefId(customRanges.getRangeId());
+            customRanges.setEndIndex(valueIndex > 0 ? valueIndex - 1 : valueIndex);
+            customRanges.setProperties(properties);
+            customRangesList.add(customRanges);
+            body.setCustomRanges(customRangesList);
+            //textRuns
+            body.setTextRuns(new ArrayList<>());
+            //customDecorations
+            body.setCustomDecorations(new ArrayList<>());
+            //sectionBreaks
+            List<UniverBodyConfig> sectionBreaksList = new ArrayList<>();
+            UniverBodyConfig sectionBreaks = new UniverBodyConfig();
+            sectionBreaks.setStartIndex(valueIndex + 1);
+            sectionBreaksList.add(sectionBreaks);
+            body.setSectionBreaks(sectionBreaksList);
+            //paragraphs
+            List<UniverBodyConfig> paragraphsList = new ArrayList<>();
+            UniverBodyConfig paragraphs = new UniverBodyConfig();
+            paragraphs.setStartIndex(valueIndex);
+            UniverBodyConfig paragraphStyle = new UniverBodyConfig();
+            paragraphStyle.setHorizontalAlign(0);
+            paragraphs.setParagraphStyle(paragraphStyle);
+            paragraphsList.add(paragraphs);
+            body.setParagraphs(paragraphsList);
+            UniverProperties p = new UniverProperties();
+            p.setBody(body);
+            p.setId("d");
+            univerSheetCellData.setP(p);
+            univerSheetCellData.setV(null);
+        }
+    }
+}

+ 174 - 0
jnpf-datareport-univer-model/pom.xml

@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.jnpf</groupId>
+        <artifactId>jnpf-datareport-univer-core</artifactId>
+        <version>6.0.0-RELEASE</version>
+    </parent>
+
+    <artifactId>jnpf-datareport-univer-model</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.jnpf</groupId>
+            <artifactId>jnpf-common-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.antlr</groupId>
+            <artifactId>antlr4-runtime</artifactId>
+            <version>4.5.3</version>
+        </dependency>
+    </dependencies>
+
+
+
+    <profiles>
+        <profile>
+            <!--JAR包加密-->
+            <id>encrypted</id>
+            <build>
+                <plugins>
+                    <!--复制驱动包, 供后续加密使用-->
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-dependency-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>copy-dependencies</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>copy-dependencies</goal>
+                                </goals>
+                                <configuration>
+                                    <includeGroupIds>com.jnpf,org.apache.poi,org.antlr,com.google.zxing</includeGroupIds>
+                                    <includeArtifactIds>jnpf-common-core,poi,antlr4-runtime,javase,core</includeArtifactIds>
+                                    <outputDirectory>${project.build.directory}/copylib</outputDirectory>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <!--安装加密打包插件-->
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-install-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>install-core</id>
+                                <phase>clean</phase>
+                                <configuration>
+                                    <file>${project.basedir}/../allatori/class-winter-core-${class-winter-maven-plugin.version}.jar</file>
+                                    <repositoryLayout>default</repositoryLayout>
+                                    <groupId>com.idea-aedi</groupId>
+                                    <artifactId>class-winter-core</artifactId>
+                                    <version>enhance-2.9.4</version>
+                                    <packaging>jar</packaging>
+                                    <generatePom>true</generatePom>
+                                </configuration>
+                                <goals>
+                                    <goal>install-file</goal>
+                                </goals>
+                            </execution>
+                            <execution>
+                                <id>install-maven</id>
+                                <phase>clean</phase>
+                                <configuration>
+                                    <file>${project.basedir}/../allatori/class-winter-maven-plugin-${class-winter-maven-plugin.version}.jar</file>
+                                    <repositoryLayout>default</repositoryLayout>
+                                    <groupId>com.idea-aedi</groupId>
+                                    <artifactId>class-winter-maven-plugin</artifactId>
+                                    <version>${class-winter-maven-plugin.version}</version>
+                                    <packaging>jar</packaging>
+                                    <generatePom>false</generatePom>
+                                    <pomFile>${project.basedir}/../allatori/class-winter-maven-plugin-pom.xml</pomFile>
+                                </configuration>
+                                <goals>
+                                    <goal>install-file</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <!--复制allatori配置重写配置中的包路径-->
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-resources-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>copy-and-filter-allatori-config</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>copy-resources</goal>
+                                </goals>
+                                <configuration>
+                                    <outputDirectory>${project.build.directory}</outputDirectory>
+                                    <resources>
+                                        <resource>
+                                            <directory>${project.basedir}/../allatori</directory>
+                                            <includes>
+                                                <include>allatori.xml</include>
+                                            </includes>
+                                            <filtering>true</filtering>
+                                        </resource>
+                                    </resources>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <!--Jar混淆-->
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>exec-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>run-allatori</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>exec</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                        <configuration>
+                            <executable>java</executable>
+                            <arguments>
+                                <argument>-Xms128m</argument>
+                                <argument>-Xmx512m</argument>
+                                <argument>-jar</argument>
+                                <!-- Copy allatori.jar to 'allatori' directory to use the commented line -->
+                                <argument>${project.basedir}/../allatori/allatori.jar</argument>
+                                <!-- <argument>${basedir}/allatori/allatori.jar</argument> -->
+                                <argument>${project.build.directory}/allatori.xml</argument>
+                            </arguments>
+                        </configuration>
+                    </plugin>
+                    <!--Jar加密-->
+                    <plugin>
+                        <groupId>com.idea-aedi</groupId>
+                        <artifactId>class-winter-maven-plugin</artifactId>
+                        <!-- 相关配置 -->
+                        <configuration>
+                            <!--需要处理的包名-->
+                            <includePrefix>jnpf</includePrefix>
+                            <!--直接覆盖原文件-->
+                            <finalName>${build.finalName}</finalName>
+                            <!--编译中依赖的第三方包路径-->
+                            <supportFile>${project.build.directory}/copylib</supportFile>
+                            <!--检查启动参数-->
+                            <jvmArgCheck>-XX:+DisableAttachMechanism</jvmArgCheck>
+                        </configuration>
+                        <executions>
+                            <execution>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>class-winter</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+
+</project>

+ 11 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/enums/CellDataEnum.java

@@ -0,0 +1,11 @@
+package jnpf.enums;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/9/10 下午4:28
+ */
+public enum CellDataEnum {
+    text, cellChart, dataSource, parameter, jsbarcode, qrcode, expression
+}

+ 31 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/enums/CellDataTypeEnum.java

@@ -0,0 +1,31 @@
+package jnpf.enums;
+
+import lombok.Getter;
+
+import java.util.Objects;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/9/10 下午4:28
+ */
+@Getter
+public enum CellDataTypeEnum {
+    String(1), Number(2), Boolean(3), Formula(4);
+    private Integer code;
+
+    CellDataTypeEnum(int code) {
+        this.code = code;
+    }
+
+    public static CellDataTypeEnum getDataType(Integer code) {
+        for (CellDataTypeEnum status : CellDataTypeEnum.values()) {
+            if (Objects.equals(status.getCode(), code)) {
+                return status;
+            }
+        }
+        return CellDataTypeEnum.String;
+    }
+
+}

+ 19 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/enums/ColumnEnum.java

@@ -0,0 +1,19 @@
+package jnpf.enums;
+
+import lombok.Getter;
+
+@Getter
+public enum ColumnEnum {
+
+    row("row", "列分栏"),
+    col("col", "行分栏"),
+    columnType("2", "1.数量分 2.分多少");
+
+    private String type;
+    private String name;
+
+    ColumnEnum(String type, String name) {
+        this.type = type;
+        this.name = name;
+    }
+}

+ 22 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/enums/FormatTypeEnum.java

@@ -0,0 +1,22 @@
+package jnpf.enums;
+
+import java.util.Objects;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/11/26 下午12:06
+ */
+public enum FormatTypeEnum {
+    highlightCell, colorScale, iconSet, dataBar;
+
+    public static FormatTypeEnum getFormat(String name) {
+        for (FormatTypeEnum status : FormatTypeEnum.values()) {
+            if (Objects.equals(status.name(), name)) {
+                return status;
+            }
+        }
+        return FormatTypeEnum.highlightCell;
+    }
+}

+ 46 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/enums/HorizontalEnum.java

@@ -0,0 +1,46 @@
+package jnpf.enums;
+
+import lombok.Getter;
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
+
+import java.util.Objects;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2025/1/6 下午6:00
+ */
+@Getter
+public enum HorizontalEnum {
+    GENERAL(0, HorizontalAlignment.GENERAL),
+    LEFT(1, HorizontalAlignment.LEFT),
+    CENTER(2, HorizontalAlignment.CENTER),
+    RIGHT(3, HorizontalAlignment.RIGHT);
+
+    private Integer code;
+    private HorizontalAlignment horizontal;
+
+    HorizontalEnum(Integer code, HorizontalAlignment horizontal) {
+        this.code = code;
+        this.horizontal = horizontal;
+    }
+
+    public static HorizontalAlignment getHorizontalValue(Integer code) {
+        for (HorizontalEnum status : HorizontalEnum.values()) {
+            if (Objects.equals(status.getCode(), code)) {
+                return status.getHorizontal();
+            }
+        }
+        return HorizontalAlignment.GENERAL;
+    }
+
+    public static Integer getHorizontalCode(HorizontalAlignment horizontal) {
+        for (HorizontalEnum status : HorizontalEnum.values()) {
+            if (Objects.equals(status.getHorizontal(), horizontal)) {
+                return status.getCode();
+            }
+        }
+        return null;
+    }
+}

+ 11 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/enums/ImageEnum.java

@@ -0,0 +1,11 @@
+package jnpf.enums;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/11/25 下午3:29
+ */
+public enum ImageEnum {
+    BASE64, URL
+}

+ 11 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/enums/OperatorEnum.java

@@ -0,0 +1,11 @@
+package jnpf.enums;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/12/4 下午4:40
+ */
+public enum OperatorEnum {
+    lessThan, greaterThan, greaterThanOrEqual, min, max, middle
+}

+ 57 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/enums/ResourceEnum.java

@@ -0,0 +1,57 @@
+
+package jnpf.enums;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/6/20 下午5:12
+ */
+public enum ResourceEnum {
+
+    /**
+     *  注释
+     */
+    SHEET_THREAD_COMMENT_PLUGIN,
+    /**
+     * 工作表权限
+     */
+    SHEET_WORKSHEET_PROTECTION_PLUGIN,
+    /**
+     * 工作表单元权限
+     */
+    SHEET_WORKSHEET_PROTECTION_POINT_PLUGIN,
+    /**
+     * 区域保护
+     */
+    SHEET_RANGE_PROTECTION_PLUGIN,
+    /**
+     * 图片
+     */
+    SHEET_DRAWING_PLUGIN,
+    /**
+     * 条件格式
+     */
+    SHEET_CONDITIONAL_FORMATTING_PLUGIN,
+    /**
+     * 超链接
+     */
+    SHEET_HYPER_LINK_PLUGIN,
+    /**
+     * 名称定义
+     */
+    SHEET_DEFINED_NAME_PLUGIN,
+    /**
+     * 数据验证
+     */
+    SHEET_DATA_VALIDATION_PLUGIN,
+    /**
+     * 过滤器
+     */
+    SHEET_FILTER_PLUGIN,
+    /**
+     * 授权服务
+     */
+    SHEET_AuthzIoMockService_PLUGIN
+
+}

+ 43 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/enums/StyleTypeEnum.java

@@ -0,0 +1,43 @@
+package jnpf.enums;
+
+import lombok.Getter;
+import org.apache.poi.ss.usermodel.BorderStyle;
+
+import java.util.Objects;
+
+@Getter
+public enum StyleTypeEnum {
+
+    NONE(0, BorderStyle.NONE),
+    THIN(1, BorderStyle.THIN),
+    HAIR(2, BorderStyle.HAIR),
+    DOTTED(3, BorderStyle.DOTTED),
+    DASHED(4, BorderStyle.DASHED),
+    DASH_DOT(5, BorderStyle.DASH_DOT),
+    DASH_DOT_DOT(6, BorderStyle.DASH_DOT_DOT),
+    DOUBLE(7, BorderStyle.DOUBLE),
+    MEDIUM(8, BorderStyle.MEDIUM),
+    MEDIUM_DASHED(9, BorderStyle.MEDIUM_DASHED),
+    MEDIUM_DASH_DOT(10, BorderStyle.MEDIUM_DASH_DOT),
+    MEDIUM_DASH_DOT_DOT(11, BorderStyle.MEDIUM_DASH_DOT_DOT),
+    SLANT_DASH_DOT(12, BorderStyle.SLANTED_DASH_DOT),
+    THICK(13, BorderStyle.THICK);
+
+    private Integer code;
+    private BorderStyle borderStyle;
+
+    StyleTypeEnum(Integer code, BorderStyle borderStyle) {
+        this.code = code;
+        this.borderStyle = borderStyle;
+    }
+
+    public static StyleTypeEnum getStyle(Integer code) {
+        for (StyleTypeEnum status : StyleTypeEnum.values()) {
+            if (Objects.equals(status.getCode(), code)) {
+                return status;
+            }
+        }
+        return null;
+    }
+
+}

+ 52 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/enums/SubTypeEnum.java

@@ -0,0 +1,52 @@
+package jnpf.enums;
+
+import lombok.Getter;
+
+import java.util.Objects;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/11/27 上午11:46
+ */
+@Getter
+public enum SubTypeEnum {
+
+    cellIs("number", "cellIs"),
+    equal("equal", "equal"),
+    notEqual("notEqual", "notEqual"),
+    top10("rank", "top10"),
+    uniqueValues("uniqueValues", "uniqueValues"),
+    duplicateValues("duplicateValues", "duplicateValues"),
+    containsText("containsText", "containsText"),
+    notContainsText("notContainsText", "notContainsText"),
+    beginsWith("beginsWith", "beginsWith"),
+    endsWith("endsWith", "endsWith"),
+    containsBlanks("containsBlanks", "containsBlanks"),
+    notContainsBlanks("notContainsBlanks", "notContainsBlanks"),
+    containsErrors("containsErrors", "containsErrors"),
+    notContainsErrors("notContainsErrors", "notContainsErrors"),
+    expression("formula", "expression"),
+    aboveAverage("average", "aboveAverage"),
+    timePeriod("timePeriod", "timePeriod"),
+    text("text", "text");
+
+
+    private String code;
+    private String type;
+
+    SubTypeEnum(String code, String type) {
+        this.code = code;
+        this.type = type;
+    }
+
+    public static SubTypeEnum getType(String type) {
+        for (SubTypeEnum status : SubTypeEnum.values()) {
+            if (Objects.equals(status.getType(), type)) {
+                return status;
+            }
+        }
+        return null;
+    }
+}

+ 50 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/enums/UniverDataEnum.java

@@ -0,0 +1,50 @@
+package jnpf.enums;
+
+import lombok.Getter;
+
+import java.util.Objects;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/11/21 下午3:15
+ */
+@Getter
+public enum UniverDataEnum {
+
+    //汇总方式
+    none(0, "无"),
+    select(1, "列表"),
+    group(2, "分组"),
+    summary(3, "汇总"),
+
+    //填充方向
+    cellDirection(4, "portrait"),
+    cellDefault(5, "default"),
+    cellNone(6, "none"),
+    cellCustom(7, "custom"),
+    cellRoot(8, "root"),
+
+    //相邻连续分组
+    adjacent(9, "adjacent"),
+
+    ;
+
+    private Integer code;
+    private String name;
+
+    UniverDataEnum(Integer code, String name) {
+        this.code = code;
+        this.name = name;
+    }
+
+    public static UniverDataEnum getData(String name) {
+        for (UniverDataEnum status : UniverDataEnum.values()) {
+            if (Objects.equals(status.getName(), name)) {
+                return status;
+            }
+        }
+        return null;
+    }
+}

+ 52 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/enums/ValidationType.java

@@ -0,0 +1,52 @@
+package jnpf.enums;
+
+import lombok.Getter;
+
+import java.util.Objects;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/12/11 上午9:41
+ */
+@Getter
+public enum ValidationType {
+
+    none("any", 0),
+    whole("whole", 1),
+    decimal("decimal", 2),
+    list("list", 3),
+    checkbox("checkbox", 3),
+    listMultiple("listMultiple", 3),
+    date("date", 4),
+    textLength("textLength", 6),
+    custom("custom", 7);
+
+    private String type;
+    private Integer validationType;
+
+    ValidationType(String type, Integer validationType) {
+        this.type = type;
+        this.validationType = validationType;
+    }
+
+    public static ValidationType getValidationType(String type) {
+        for (ValidationType status : ValidationType.values()) {
+            if (Objects.equals(status.getType(), type)) {
+                return status;
+            }
+        }
+        return ValidationType.none;
+    }
+
+    public static ValidationType getType(Integer validationType) {
+        for (ValidationType status : ValidationType.values()) {
+            if (Objects.equals(status.getValidationType(), validationType)) {
+                return status;
+            }
+        }
+        return ValidationType.none;
+    }
+
+}

+ 46 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/enums/VerticalEnum.java

@@ -0,0 +1,46 @@
+package jnpf.enums;
+
+import lombok.Getter;
+import org.apache.poi.ss.usermodel.VerticalAlignment;
+
+import java.util.Objects;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2025/1/6 下午5:54
+ */
+@Getter
+public enum VerticalEnum {
+    TOP(1, VerticalAlignment.TOP),
+    CENTER(2, VerticalAlignment.CENTER),
+    BOTTOM(3, VerticalAlignment.BOTTOM);
+
+    private Integer code;
+    private VerticalAlignment vertical;
+
+    VerticalEnum(Integer code, VerticalAlignment vertical) {
+        this.code = code;
+        this.vertical = vertical;
+    }
+
+    public static VerticalAlignment getVerticalValue(Integer code) {
+        for (VerticalEnum status : VerticalEnum.values()) {
+            if (Objects.equals(status.getCode(), code)) {
+                return status.getVertical();
+            }
+        }
+        return null;
+    }
+
+    public static Integer getVerticalCode(VerticalAlignment vertical) {
+        for (VerticalEnum status : VerticalEnum.values()) {
+            if (Objects.equals(status.getVertical(), vertical)) {
+                return status.getCode();
+            }
+        }
+        return null;
+    }
+
+}

+ 37 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/enums/ZxingEnum.java

@@ -0,0 +1,37 @@
+package jnpf.enums;
+
+import lombok.Getter;
+
+import java.util.Objects;
+
+@Getter
+public enum ZxingEnum {
+    BARCODE("jsbarcode","jsbarcode"),
+    QRCODE("qrCode", "qrCode"),
+    DEFAULT("default","default"),
+
+    CODE128("code128","CODE_128"),
+    EAN13("ean13","EAN_13"),
+    EAN8("ean8","EAN_8"),
+    CODE39("code39","CODE_39"),
+    ITF("itf14","ITF"),
+    CODABAR("codabar","CODABAR"),
+
+    ;
+
+    private String type;
+    private String value;
+    ZxingEnum(String type, String value) {
+        this.type = type;
+        this.value = value;
+    }
+
+    public static ZxingEnum getType(String type) {
+        for (ZxingEnum status : ZxingEnum.values()) {
+            if (Objects.equals(status.getType(), type)) {
+                return status;
+            }
+        }
+        return ZxingEnum.DEFAULT;
+    }
+}

+ 51 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/enums/operatorTypeEnum.java

@@ -0,0 +1,51 @@
+package jnpf.enums;
+
+import lombok.Getter;
+
+import java.util.Objects;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/12/11 下午3:15
+ */
+@Getter
+public enum operatorTypeEnum {
+
+    none("none", -1),
+    between("between", 0),
+    notBetween("notBetween", 1),
+    equal("equal", 2),
+    NOT_EQUAL("notEqual", 3),
+    greaterThan("greaterThan", 4),
+    lessThan("lessThan", 5),
+    greaterThanOrEqual("greaterThanOrEqual", 6),
+    lessThanOrEqual("lessThanOrEqual", 7);
+
+    private String operatorType;
+    private Integer operator;
+
+    operatorTypeEnum(String operatorType, Integer operator) {
+        this.operatorType = operatorType;
+        this.operator = operator;
+    }
+
+    public static operatorTypeEnum getOperator(String operatorType) {
+        for (operatorTypeEnum status : operatorTypeEnum.values()) {
+            if (Objects.equals(status.getOperatorType(), operatorType)) {
+                return status;
+            }
+        }
+        return operatorTypeEnum.none;
+    }
+
+    public static operatorTypeEnum getOperator(Integer operator) {
+        for (operatorTypeEnum status : operatorTypeEnum.values()) {
+            if (Objects.equals(status.getOperator(), operator)) {
+                return status;
+            }
+        }
+        return null;
+    }
+}

+ 51 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/model/ColumnList.java

@@ -0,0 +1,51 @@
+package jnpf.model;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Data
+public class ColumnList {
+
+    @Schema(description = "是否启用分栏")
+    private boolean columnState;
+
+    @Schema(description = "分栏类型 row-列分栏,col-行分栏")
+    private String columnStyle;
+
+    @Schema(description = "分栏类型 2-分成多少列,超出多少数量分栏")
+    private String columnType;
+
+    @Schema(description = "")
+    private Integer maxCol;
+
+    @Schema(description = "")
+    private Integer rowCount;
+
+    @Schema(description = "超过列号数量")
+    private Integer maxRow;
+
+    @Schema(description = "超过行号数量")
+    private Integer colCount;
+
+    @Schema(description = "分栏数据")
+    private String columnData;
+
+    @Schema(description = "复制列号")
+    private String copyCol;
+
+    @Schema(description = "复制行号")
+    private String copyRow;
+
+    @Schema(description = "是否填充空白格")
+    private boolean fillEmptyRows;
+
+
+    @Schema(description = "分栏数据行范围")
+    private Integer rowMaxNum;
+
+    private Integer rowMinNum;
+    @Schema(description = "分栏数据列范围")
+    private Integer colMaxNum;
+
+    private Integer colMinNum;
+}

+ 20 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/model/DataQuery.java

@@ -0,0 +1,20 @@
+package jnpf.model;
+
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/11/26 上午11:31
+ */
+@Data
+public class DataQuery {
+    private String sheet;
+    private String sheetName;
+    private List<Object> queryList = new ArrayList<>();
+    private List<DataSortModel> sortList = new ArrayList<>();
+}

+ 16 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/model/DataSortModel.java

@@ -0,0 +1,16 @@
+package jnpf.model;
+
+import lombok.Data;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/12/6 下午2:12
+ */
+@Data
+public class DataSortModel {
+    private String id;
+    private String vModel;
+    private String type;
+}

+ 19 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/model/Fence.java

@@ -0,0 +1,19 @@
+package jnpf.model;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Data
+public class Fence {
+
+    @Schema(description = "sheet")
+    private String sheet;
+
+    @Schema(description = "sheet名称")
+    private String sheetName;
+
+    @Schema(description = "分栏设置")
+    private ColumnList columnList;
+
+
+}

+ 25 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/chart/UniverChartField.java

@@ -0,0 +1,25 @@
+package jnpf.univer.chart;
+
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/9/10 下午1:29
+ */
+@Data
+public class UniverChartField {
+    //维度
+    private List<String> seriesNameField = new ArrayList<>();
+    //系列
+    private List<String> classifyNameField = new ArrayList<>();
+    //值
+    private List<List<String>> seriesDataField = new ArrayList<>();
+    //最大值
+    private List<String> maxField = new ArrayList<>();
+
+}

+ 18 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/chart/UniverChartModel.java

@@ -0,0 +1,18 @@
+package jnpf.univer.chart;
+
+import lombok.Data;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/9/10 下午1:26
+ */
+@Data
+public class UniverChartModel {
+    private String unitId;
+    private String subUnitId;
+    private String drawingId;
+    private UniverChartField field = new UniverChartField();
+    private String source;
+}

+ 20 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/data/cell/UniverCell.java

@@ -0,0 +1,20 @@
+package jnpf.univer.data.cell;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/8/1 下午8:54
+ */
+@Data
+public class UniverCell implements Serializable {
+    private String sheet;
+    private Integer row;
+    private Integer col;
+    private String drawingId;
+    private String domId;
+}

+ 57 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/data/cell/UniverDataConfig.java

@@ -0,0 +1,57 @@
+package jnpf.univer.data.cell;
+
+import jnpf.enums.CellDataEnum;
+import jnpf.enums.UniverDataEnum;
+import jnpf.enums.ZxingEnum;
+import jnpf.univer.zxing.UniverZxingModel;
+import jnpf.ureport.definition.value.AggregateType;
+import lombok.Data;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/5/11 下午4:35
+ */
+@Data
+public class UniverDataConfig {
+    //dataSource
+    private Integer col;
+    private Integer row;
+    private String sheet;
+    private String type = CellDataEnum.text.name();
+    private UniverDataConfig custom;
+    private String field;
+    //0.无 1.列表 2. 分组 3.汇总
+    private Integer polymerizationType = 1;
+    //汇总方式
+    private String summaryType = AggregateType.sum.name();
+    private String fillDirection = UniverDataEnum.cellDirection.getName();
+    private String leftParentCellType = UniverDataEnum.cellNone.getName();
+    private String leftParentCellCustomRowName;
+    private String leftParentCellCustomColName;
+    private String topParentCellType = UniverDataEnum.cellNone.getName();
+    private String topParentCellCustomRowName;
+    private String topParentCellCustomColName;
+    //补充空白行
+    private Boolean fillEmptyRows = false;
+    private Integer fillEmptyNum = 1;
+    //相邻连续分组
+    private String groupType = UniverDataEnum.cellDefault.getName();
+    //显示类型
+    private String displayType = ZxingEnum.DEFAULT.getType();
+    private UniverZxingModel qrCodeOption;
+    private UniverZxingModel jsbarCodeOption;
+
+
+    //echarts
+    private String drawingId;
+    private String unitId;
+    private String subUnitId;
+    private UniverDataConfig option;
+    private String classifyNameField;
+    private String seriesNameField;
+    private String seriesDataField;
+    private String maxField;
+
+}

+ 20 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/data/custom/UniverCustom.java

@@ -0,0 +1,20 @@
+package jnpf.univer.data.custom;
+
+import jnpf.univer.data.cell.UniverDataConfig;
+import lombok.Data;
+
+import java.util.*;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/11/25 下午2:49
+ */
+@Data
+public class UniverCustom {
+    private List<UniverDataConfig> cells = new ArrayList<>();
+    private Map<String, UniverDataConfig> floatEcharts = new HashMap<>();
+    private Map<String, UniverDataConfig> cellEcharts = new HashMap<>();
+    private Map<String, UniverDataConfig> floatImages = new HashMap<>();
+}

+ 27 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/data/resource/UniverConfig.java

@@ -0,0 +1,27 @@
+package jnpf.univer.data.resource;
+
+import lombok.Data;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/11/21 上午11:06
+ */
+@Data
+public class UniverConfig {
+    private String operator;
+    private UniverValue value;
+    private String iconType;
+    private String iconId;
+    private Integer index;
+    private String color;
+
+    private UniverValue min;
+    private UniverValue max;
+    private Boolean isGradient;
+    private String positiveColor;
+    private String nativeColor;
+
+
+}

+ 20 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/data/resource/UniverCustomFilters.java

@@ -0,0 +1,20 @@
+package jnpf.univer.data.resource;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/10/18 下午1:58
+ */
+@Data
+public class UniverCustomFilters {
+    private List<UniverCustomFilters> customFilters;
+    private List<String> filters;
+    private String val;
+    private String operator;
+    private Integer and;
+}

+ 9 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/data/resource/UniverData.java

@@ -0,0 +1,9 @@
+package jnpf.univer.data.resource;
+
+import lombok.Data;
+
+@Data
+public class UniverData {
+    private String id;
+    private String piniaStoreId;
+}

+ 40 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/data/resource/UniverDrawing.java

@@ -0,0 +1,40 @@
+package jnpf.univer.data.resource;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ *
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/5/11 下午4:35
+ */
+@Data
+public class UniverDrawing implements Serializable {
+    private String unitId;
+    private String subUnitId;
+    private String drawingId;
+    private Integer drawingType;
+    private String imageSourceType;
+    private String source;
+    private Boolean allowTransform;
+    private String componentKey;
+    //悬浮图片
+    private UniverTransform sheetTransform;
+    //单元格图片
+    private UniverTransform docTransform;
+    private UniverTransform transform;
+    private Integer behindDoc;
+    private String title;
+    private String description;
+    private Integer layoutType;
+    private Integer wrapText;
+    private Integer distB;
+    private Integer distL;
+    private Integer distR;
+    private Integer distT;
+
+    private UniverData data;
+}

+ 16 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/data/resource/UniverFilters.java

@@ -0,0 +1,16 @@
+package jnpf.univer.data.resource;
+
+import lombok.Data;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/10/18 下午1:58
+ */
+@Data
+public class UniverFilters {
+    private UniverCustomFilters filters;
+    private UniverCustomFilters customFilters;
+    private Long colId;
+}

+ 17 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/data/resource/UniverNum.java

@@ -0,0 +1,17 @@
+package jnpf.univer.data.resource;
+
+import lombok.Data;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/5/24 下午1:31
+ */
+@Data
+public class UniverNum {
+    private String i;
+    private Integer row;
+    private Integer col;
+    private String sheet;
+}

+ 17 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/data/resource/UniverOffset.java

@@ -0,0 +1,17 @@
+package jnpf.univer.data.resource;
+
+import lombok.Data;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/9/10 下午6:12
+ */
+@Data
+public class UniverOffset {
+    private Integer column;
+    private Integer columnOffset;
+    private Integer row;
+    private Integer  rowOffset;
+}

+ 20 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/data/resource/UniverRef.java

@@ -0,0 +1,20 @@
+package jnpf.univer.data.resource;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/5/22 上午11:41
+ */
+@Data
+public class UniverRef implements Serializable {
+    private Integer count;
+    private String i;
+    private String pattern;
+    private String type;
+
+}

+ 23 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/data/resource/UniverRule.java

@@ -0,0 +1,23 @@
+package jnpf.univer.data.resource;
+
+import jnpf.univer.style.UniverStyle;
+import lombok.Data;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/5/22 上午11:33
+ */
+@Data
+public class UniverRule {
+    private String type;
+    private String subType;
+    private String operator;
+    private UniverStyle style;
+    private Object value;
+    private Boolean isShowValue;
+    private Object config;
+    private Boolean isPercent;
+    private Boolean isBottom;
+}

+ 34 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/data/resource/UniverTransform.java

@@ -0,0 +1,34 @@
+package jnpf.univer.data.resource;
+
+import lombok.Data;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/9/10 下午6:09
+ */
+@Data
+public class UniverTransform {
+    //悬浮图片
+    private Boolean flipY;
+    private Boolean flipX;
+    private Integer skewX;
+    private Integer skewY;
+    private UniverOffset from;
+    private UniverOffset to;
+
+    //单元格图片
+    private Integer relativeFrom;
+    private Integer posOffset;
+    private UniverTransform size;
+    private UniverTransform positionH;
+    private UniverTransform positionV;
+
+    //图片公共
+    private Integer angle;
+    private Integer left;
+    private Integer top;
+    private Integer width;
+    private Integer height;
+}

+ 15 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/data/resource/UniverValue.java

@@ -0,0 +1,15 @@
+package jnpf.univer.data.resource;
+
+import lombok.Data;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/11/21 上午11:09
+ */
+@Data
+public class UniverValue {
+    private Object value;
+    private String type;
+}

+ 36 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/model/UniverPreview.java

@@ -0,0 +1,36 @@
+package jnpf.univer.model;
+
+import lombok.Data;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/7/4 下午4:12
+ */
+@Data
+public class UniverPreview {
+
+    private String cells;
+
+    private String snapshot;
+
+    private String queryList;
+
+    private String chartData;
+
+    private String fullName;
+
+    private String versionId;
+
+    private Integer allowExport;
+
+    private Integer allowPrint;
+
+    private Integer allowWatermark;
+
+    private String watermarkConfig;
+
+    private String columnList;
+
+}

+ 37 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/model/UniverWorkBook.java

@@ -0,0 +1,37 @@
+package jnpf.univer.model;
+
+import jnpf.univer.resources.UniverResource;
+import jnpf.univer.sheet.UniverSheet;
+import jnpf.univer.style.UniverStyle;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.*;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/5/11 下午4:35
+ */
+@Data
+public class UniverWorkBook implements Serializable {
+    private String id;
+    private Integer rev;
+    private String name;
+    /**
+     * Univer版本
+     */
+    private String appVersion = "0.4.1";
+    /**
+     * Univer语言
+     */
+    private String locale = "zhCN";
+    /**
+     * 样式列表
+     */
+    private Map<String, UniverStyle> styles = new HashMap<>();
+    private List<String> sheetOrder = new ArrayList<>();
+    private Map<String, UniverSheet> sheets = new HashMap<>();
+    private List<UniverResource> resources = new ArrayList<>();
+}

+ 24 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/properties/UniverBody.java

@@ -0,0 +1,24 @@
+package jnpf.univer.properties;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/11/5 下午3:58
+ */
+@Data
+public class UniverBody {
+    private String dataStream;
+    private List<UniverBodyConfig> textRuns;
+    private List<UniverBodyConfig> tables;
+    private List<UniverBodyConfig> sectionBreaks;
+    private List<UniverBodyConfig> paragraphs;
+    private List<UniverBodyConfig> customDecorations;
+    private List<UniverBodyConfig> customBlocks;
+    private List<UniverBodyConfig> customRanges;
+    private UniverBodyConfig settings;
+}

+ 67 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/properties/UniverBodyConfig.java

@@ -0,0 +1,67 @@
+
+package jnpf.univer.properties;
+
+import jnpf.univer.style.UniverStyle;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/11/5 下午4:08
+ */
+@Data
+public class UniverBodyConfig {
+    //customRanges
+    private String rangeId;
+    private Integer rangeType;
+    private String url;
+    private String refId;
+    private Boolean wholeEntity;
+    private UniverBodyConfig properties;
+
+    //paragraphs
+    private UniverBodyConfig paragraphStyle;
+
+    //textRuns
+    private Integer st;
+    private Integer ed;
+    private UniverStyle ts;
+
+    //documentStyle
+    private BigDecimal width;
+    private BigDecimal height;
+    private UniverBodyConfig pageSize;
+    private Integer marginTop;
+    private Integer marginBottom;
+    private Integer marginLeft;
+    private Integer marginRight;
+    private UniverBodyConfig renderConfig;
+    private Integer verticalAlign;
+    private Integer centerAngle;
+    private Integer vertexAngle;
+    private Integer wrapStrategy;
+    private Integer zeroWidthParagraphBreak;
+
+    //settings
+    private Integer zoomRatio;
+
+    //customDecorations
+    private String id;
+    private UniverBodyConfig type;
+    private UniverBodyConfig customDecorations;
+
+    //paragraphs、documentStyle
+    private Integer horizontalAlign;
+
+    //sectionBreaks、customRanges、paragraphs、customDecorations、customBlocks
+    private Integer startIndex;
+
+    //customDecorations.customRanges
+    private Integer endIndex;
+
+    //customBlocks
+    private String blockId;
+}

+ 43 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/properties/UniverDocumentStyle.java

@@ -0,0 +1,43 @@
+package jnpf.univer.properties;
+
+import jnpf.univer.style.UniverStyle;
+import lombok.Data;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/11/5 下午3:55
+ */
+@Data
+public class UniverDocumentStyle {
+
+    private Integer autoHyphenation;
+    private Integer characterSpacingControl;
+    private Integer consecutiveHyphenLimit;
+    private String defaultFooterId;
+    private String defaultHeaderId;
+    private Integer defaultTabStop;
+    private Integer doNotHyphenateCaps;
+    private Integer documentFlavor;
+    private Integer evenAndOddHeaders;
+    private String evenPageFooterId;
+    private String evenPageHeaderId;
+    private String firstPageFooterId;
+    private String firstPageHeaderId;
+    private Integer hyphenationZone;
+    private Integer marginBottom;
+    private Integer marginFooter;
+    private Integer marginHeader;
+    private Integer marginLeft;
+    private Integer marginRight;
+    private Integer marginTop;
+    private Integer pageNumberStart;
+    private Integer pageOrient;
+    private UniverDocumentStyleConfig pageSize;
+    private Integer paragraphLineGapDefault;
+    private UniverDocumentStyleConfig renderConfig;
+    private Boolean spaceWidthEastAsian;
+    private UniverStyle textStyle;
+    private Boolean useFirstPageHeaderFooter;
+}

+ 22 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/properties/UniverDocumentStyleConfig.java

@@ -0,0 +1,22 @@
+package jnpf.univer.properties;
+
+import lombok.Data;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/11/5 下午3:55
+ */
+@Data
+public class UniverDocumentStyleConfig {
+    private Integer width;
+    private Integer height;
+    private Object background;
+    private Integer horizontalAlign;
+    private Integer verticalAlign;
+    private Integer centerAngle;
+    private Integer vertexAngle;
+    private Integer wrapStrategy;
+    private Integer zeroWidthParagraphBreak;
+}

+ 33 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/properties/UniverProperties.java

@@ -0,0 +1,33 @@
+package jnpf.univer.properties;
+
+import jnpf.univer.data.resource.UniverDrawing;
+import lombok.Data;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/11/5 下午5:54
+ */
+@Data
+public class UniverProperties {
+    private UniverBody body;
+    private Boolean disabled;
+    private UniverDocumentStyle documentStyle;
+    private Map<String, UniverDrawing> drawings;
+    private List<String> drawingsOrder;
+    private Map<String,Object> footers;
+    private List<String> headerFooterDrawingsOrder;
+    private Map<String,Object> headers;
+    private String id;
+    private Map<String,Object> lists;
+    private String locale;
+    private Map<String,Object> resources;
+    private Integer rev;
+    private UniverBodyConfig settings;
+    private Map<String,Object> tableSource;
+    private String title;
+}

+ 16 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/resources/UniverResource.java

@@ -0,0 +1,16 @@
+package jnpf.univer.resources;
+
+import lombok.Data;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/5/11 下午4:35
+ */
+@Data
+public class UniverResource{
+    private String id;
+    private String name;
+    private String data;
+}

+ 67 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/resources/UniverResourceData.java

@@ -0,0 +1,67 @@
+package jnpf.univer.resources;
+
+import jnpf.univer.data.resource.*;
+import jnpf.univer.sheet.UniverSheetRange;
+import lombok.Data;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/5/22 下午2:10
+ */
+@Data
+public class UniverResourceData {
+    //SHEET_DATA_VALIDATION
+    private String uid;
+    private String operator;
+    private String formula1;
+    private String formula2;
+    private String error;
+    private Integer renderMode;
+    private Boolean allowBlank;
+    private Integer errorStyle;
+    private Boolean showErrorMessage;
+
+    //SHEET_NUMFMT_PLUGIN
+    private Map<String, Map<Integer, Map<Integer, UniverNum>>> model;
+    private List<UniverRef> refModel;
+    private List<UniverNum> numModel;
+
+    //SHEET_CONDITIONAL_FORMATTING_PLUGIN
+    private String cfId;
+    private UniverRule rule;
+    private Boolean stopIfTrue;
+
+    //SHEET_CONDITIONAL_FORMATTING_PLUGIN、SHEET_DATA_VALIDATION、SHEET_RANGE_PROTECTION
+    private List<UniverSheetRange> ranges;
+
+    //SHEET_NUMFMT_PLUGIN、SHEET_DATA_VALIDATION
+    private String type;
+
+    //SHEET_DEFINED_NAME_PLUGIN
+    private String id;
+    private String name;
+    private String formulaOrRefString;
+    private String comment;
+    private String localSheetId;
+
+    //SHEET_RANGE_PROTECTION
+    private String permissionId;
+    private String unitType;
+    private String unitId;
+    private String subUnitId;
+
+    //SHEET_DRAWING_PLUGIN
+    private List<String> order;
+    private Map<String, UniverDrawing> data;
+
+    //SHEET_FILTER_PLUGIN
+    private UniverSheetRange ref;
+    private List<UniverFilters> filterColumns;
+    private List<Integer> cachedFilteredOut;
+
+}

+ 38 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/sheet/UniverSheet.java

@@ -0,0 +1,38 @@
+package jnpf.univer.sheet;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/5/11 下午4:35
+ */
+@Data
+public class UniverSheet implements Serializable {
+    private String id;
+    private String name;
+    private String tabColor;
+    private Integer hidden;
+    private UniverSheetFreeze freeze;
+    private Integer rowCount;
+    private Integer columnCount;
+    private Integer zoomRatio;
+    private Integer scrollTop;
+    private Integer scrollLeft;
+    private Integer defaultColumnWidth = 88;
+    private Integer defaultRowHeight = 24;
+    private List<UniverSheetRange> mergeData;
+    private Map<Integer, Map<Integer, UniverSheetCellData>> cellData;
+    private Map<Integer, UniverSheetRowData> rowData;
+    private Map<Integer, UniverSheetColumnData> columnData;
+    private UniverSheetRowHeader rowHeader;
+    private UniverSheetColumnHeader columnHeader;
+    private Integer showGridlines;
+    private List<String> selections;
+    private Integer rightToLeft;
+}

+ 17 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/sheet/UniverSheetCell.java

@@ -0,0 +1,17 @@
+package jnpf.univer.sheet;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/5/11 下午4:35
+ */
+@Data
+public class UniverSheetCell implements Serializable {
+    private Integer row;
+    private Integer column;
+}

+ 43 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/sheet/UniverSheetCellData.java

@@ -0,0 +1,43 @@
+package jnpf.univer.sheet;
+
+import jnpf.ureport.model.Formula;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/5/11 下午4:35
+ */
+@Data
+public class UniverSheetCellData implements Serializable {
+    /**
+     * The unique key, a random string, is used for the plug-in to associate the cell. When the cell information changes,
+     * the plug-in does not need to change the data, reducing the pressure on the back-end interface id?: string.
+     */
+    private Object p;
+
+    /**
+     * style id
+     * UniverStyle | String
+     */
+    private Object s;
+
+    /**
+     * Origin value
+     * String | Integer | Boolean
+     */
+    private Object v;
+
+    // Usually the type is automatically determined based on the data, or the user directly specifies
+    // 1 string, 2 number, 3 boolean, 4 force string, green icon, set null for cell clear all
+    private Integer t;
+
+    /**
+     * Raw formula string. For example `=SUM(A1:B4)`.
+     */
+    private String f;
+
+}

+ 23 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/sheet/UniverSheetColumnData.java

@@ -0,0 +1,23 @@
+package jnpf.univer.sheet;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/5/11 下午4:35
+ */
+@Data
+public class UniverSheetColumnData implements Serializable {
+    /**
+     * width
+     */
+    private Integer w;
+    /**
+     * hidden
+     */
+    private Integer hd;
+}

+ 17 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/sheet/UniverSheetColumnHeader.java

@@ -0,0 +1,17 @@
+package jnpf.univer.sheet;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/5/11 下午4:35
+ */
+@Data
+public class UniverSheetColumnHeader implements Serializable {
+    private Integer height;
+    private Integer hidden;
+}

+ 19 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/sheet/UniverSheetFreeze.java

@@ -0,0 +1,19 @@
+package jnpf.univer.sheet;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/5/11 下午4:35
+ */
+@Data
+public class UniverSheetFreeze implements Serializable {
+    private Integer xSplit = 0;
+    private Integer ySplit = 0;
+    private Integer startRow = -1;
+    private Integer startColumn = -1;
+}

+ 47 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/sheet/UniverSheetRange.java

@@ -0,0 +1,47 @@
+package jnpf.univer.sheet;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/5/11 下午4:35
+ */
+@Data
+public class UniverSheetRange implements Serializable {
+    /**
+     * The start row (inclusive) of the range
+     * startRow
+     */
+    private Integer startRow;
+
+    /**
+     * The end row (exclusive) of the range
+     * endRow
+     */
+    private Integer endRow;
+    /**
+     * The start column (inclusive) of the range
+     * startColumn
+     */
+    private Integer startColumn;
+
+    /**
+     * The end column (exclusive) of the range
+     * endColumn
+     */
+    private Integer endColumn;
+
+    private Integer rangeType;
+
+    private Integer startAbsoluteRefType;
+
+    private Integer endAbsoluteRefType;
+
+    private String unitId;
+
+    private String sheetId;
+}

+ 31 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/sheet/UniverSheetRowData.java

@@ -0,0 +1,31 @@
+package jnpf.univer.sheet;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/5/11 下午4:35
+ */
+@Data
+public class UniverSheetRowData implements Serializable {
+    /**
+     * height in pixel
+     */
+    private Integer h;
+    /**
+     * is current row self-adaptive to its content, use `ah` to set row height when true, else use `h`.
+     */
+    private Integer ia; // pre name `isAutoHeight`
+    /**
+     * auto height
+     */
+    private Integer ah;
+    /**
+     * hidden
+     */
+    private Integer hd;
+}

+ 17 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/sheet/UniverSheetRowHeader.java

@@ -0,0 +1,17 @@
+package jnpf.univer.sheet;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/5/11 下午4:35
+ */
+@Data
+public class UniverSheetRowHeader implements Serializable {
+    private Integer width;
+    private Integer hidden;
+}

+ 98 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/style/UniverStyle.java

@@ -0,0 +1,98 @@
+package jnpf.univer.style;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/5/11 下午4:35
+ */
+@Data
+public class UniverStyle implements Serializable {
+    /**
+     * fontFamily
+     */
+    private String ff;
+    /**
+     * fontSize
+     * <p>
+     * pt
+     */
+    private Integer fs;
+    /**
+     * italic
+     * 0: false
+     * 1: true
+     */
+    private Integer it;
+    /**
+     * bold
+     * 0: false
+     * 1: true
+     */
+    private Integer bl;
+
+    /**
+     * underline
+     */
+    private UniverStyleTextDecoration ul;
+    /**
+     * strikethrough
+     */
+    private UniverStyleTextDecoration st;
+    /**
+     * overline
+     */
+    private UniverStyleTextDecoration ol;
+
+    /**
+     * background
+     */
+    private UniverStyleColor bg;
+
+    /**
+     * border
+     */
+    private UniverStyleBorder bd;
+
+    /**
+     * foreground
+     */
+    private UniverStyleColor cl;
+
+    /**
+     * (1.正常 2.Subscript 下标 3.Superscript上标 )
+     */
+    private Integer va;
+    /**
+     * textRotation
+     */
+    private UniverStyleTextRotation tr;
+    /**
+     * textDirection
+     */
+    private Integer td;
+    /**
+     * horizontalAlignment
+     */
+    private Integer ht;
+    /**
+     * verticalAlignment
+     */
+    private Integer vt;
+    /**
+     * wrapStrategy
+     */
+    private Integer tb;
+    /**
+     * padding
+     */
+    private UniverStylePadding pd;
+    /**
+     * dataFormat
+     */
+    private UniverStylePattern n;
+}

+ 35 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/style/UniverStyleBorder.java

@@ -0,0 +1,35 @@
+package jnpf.univer.style;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * Style properties of top, bottom, left and right border
+ * TLBR = 'tlbr', //START_TOP_LEFT_END_BOTTOM_RIGHT
+ * TLBC = 'tlbc', // START_TOP_LEFT_END_BOTTOM_CENTER
+ * TLMR = 'tlmr', // START_TOP_LEFT_END_MIDDLE_RIGHT
+ * BLTR = 'bltr', // START_BOTTOM_LEFT_END_TOP_RIGHT
+ * MLTR = 'mltr', // START_MIDDLE_LEFT_END_TOP_RIGHT
+ * BCTR = 'bctr', // START_BOTTOM_CENTER_END_TOP_RIGHT
+ *
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/5/11 下午4:35
+ */
+@Data
+public class UniverStyleBorder implements Serializable {
+    private UniverStyleBorderStyle t;
+    private UniverStyleBorderStyle r;
+    private UniverStyleBorderStyle b;
+    private UniverStyleBorderStyle l;
+
+    private UniverStyleBorderStyle tl_br;
+    private UniverStyleBorderStyle tl_bc;
+    private UniverStyleBorderStyle tl_mr;
+
+    private UniverStyleBorderStyle bl_tr;
+    private UniverStyleBorderStyle ml_tr;
+    private UniverStyleBorderStyle bc_tr;
+}

+ 17 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/style/UniverStyleBorderStyle.java

@@ -0,0 +1,17 @@
+package jnpf.univer.style;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/5/11 下午4:35
+ */
+@Data
+public class UniverStyleBorderStyle implements Serializable {
+    private Integer s;
+    private UniverStyleColor cl;
+}

+ 17 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/style/UniverStyleColor.java

@@ -0,0 +1,17 @@
+package jnpf.univer.style;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/5/11 下午4:35
+ */
+@Data
+public class UniverStyleColor implements Serializable {
+    private String rgb;
+    private Object th;
+}

+ 19 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/style/UniverStylePadding.java

@@ -0,0 +1,19 @@
+package jnpf.univer.style;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/5/11 下午4:35
+ */
+@Data
+public class UniverStylePadding implements Serializable {
+    private Integer t;
+    private Integer r;
+    private Integer b;
+    private Integer l;
+}

+ 14 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/style/UniverStylePattern.java

@@ -0,0 +1,14 @@
+package jnpf.univer.style;
+
+import lombok.Data;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/9/6 上午9:00
+ */
+@Data
+public class UniverStylePattern {
+    private String pattern;
+}

+ 23 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/style/UniverStyleTextDecoration.java

@@ -0,0 +1,23 @@
+package jnpf.univer.style;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/5/11 下午4:35
+ */
+@Data
+public class UniverStyleTextDecoration implements Serializable {
+    // show
+    private Integer s;
+    // color is follow the font color. the default value is TRUE, it's also TRUE if it is undefined. the cl has no effect when `c` is TRUE.
+    private Integer c;
+    // color
+    private UniverStyleColor cl;
+    // lineType
+    private Object t;
+}

+ 25 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/style/UniverStyleTextRotation.java

@@ -0,0 +1,25 @@
+package jnpf.univer.style;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/5/11 下午4:35
+ */
+@Data
+public class UniverStyleTextRotation implements Serializable {
+    /**
+     * angle
+     */
+    private int a;
+    /**
+     * vertical
+     * true : 1
+     * false : 0
+     */
+    private int v;
+}

+ 40 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/univer/zxing/UniverZxingModel.java

@@ -0,0 +1,40 @@
+package jnpf.univer.zxing;
+
+import lombok.Data;
+
+/**
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2024/9/10 下午1:26
+ */
+@Data
+public class UniverZxingModel {
+
+    private String text;
+    private Integer height;
+    private String displayType;
+
+    //条形码
+    private String dark;
+    private String light;
+    private UniverZxingModel color;
+    private String errorCorrectionLevel;
+
+    //二维码
+    private String format;
+    private Boolean displayValue;
+    private String lineColor;
+    private String background;
+    private Integer width;
+    private Integer margin;
+    private String font;
+    private Integer fontSize;
+    private String textAlign;
+    private String textPosition;
+
+    private Integer univerWidth;
+    private Integer univerHeight;
+
+
+}

+ 16 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/ureport/Range.java

@@ -0,0 +1,16 @@
+package jnpf.ureport;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+
+@Setter
+@Getter
+@NoArgsConstructor
+@AllArgsConstructor
+public class Range {
+    private int start = -1;
+    private int end;
+}

+ 16 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/ureport/build/BindData.java

@@ -0,0 +1,16 @@
+package jnpf.ureport.build;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+import java.util.Map;
+
+
+@Setter
+@Getter
+public class BindData {
+    private Object value;
+    private List<Map<String, Object>> dataList;
+
+}

+ 173 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/ureport/build/Context.java

@@ -0,0 +1,173 @@
+package jnpf.ureport.build;
+
+import jnpf.ureport.definition.value.SimpleValue;
+import jnpf.ureport.definition.value.Value;
+import jnpf.ureport.expression.util.ElCompute;
+import jnpf.ureport.model.Cell;
+import jnpf.ureport.model.Column;
+import jnpf.ureport.model.Report;
+import jnpf.ureport.model.Row;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.*;
+
+
+@Getter
+@Setter
+public class Context {
+    private Report report;
+    private Cell rootCell;
+    private ReportBuilder reportBuilder;
+    private Map<String, Dataset> datasetMap;
+    private Map<String, Object> variableMap = new HashMap<>();
+    private Map<Integer, List<Row>> currentPageRowsMap = new HashMap<>();
+    private Map<Row, Map<Column, Cell>> blankCellsMap = new HashMap<>();
+    private Map<String, List<Cell>> unprocessedCellsMap = new HashMap<>();
+    private Map<String, Map<Row, Integer>> fillBlankRowsMap = new HashMap<>();
+
+    public Context(ReportBuilder reportBuilder, Report report, Map<String, Dataset> datasetMap) {
+        this.reportBuilder = reportBuilder;
+        this.report = report;
+        report.setContext(this);
+        this.datasetMap = datasetMap;
+        Map<String, List<Cell>> cellsMap = report.getCellsMap();
+        for (String key : cellsMap.keySet()) {
+            if (key.equals(report.getRootCell().getName())) {
+                continue;
+            }
+            List<Cell> list = new ArrayList<>();
+            list.addAll(cellsMap.get(key));
+            unprocessedCellsMap.put(key, list);
+        }
+        this.rootCell = new Cell();
+        this.rootCell.setName("ROOT");
+    }
+
+    public List<Cell> nextUnprocessedCells() {
+        if (unprocessedCellsMap.size() == 0) {
+            return null;
+        }
+        List<Cell> targetCellsList = null;
+        String targetCellName = null;
+        Set<String> keySet = unprocessedCellsMap.keySet();
+        for (String cellName : keySet) {
+            List<Cell> cells = unprocessedCellsMap.get(cellName);
+            Cell cell = cells.get(0);
+            Value value = cell.getValue();
+            Cell leftParent = cell.getLeftParentCell();
+            Cell topParent = cell.getTopParentCell();
+            if ((leftParent == null || leftParent.isProcessed()) && (topParent == null || topParent.isProcessed())) {
+                targetCellsList = cells;
+                targetCellName = cellName;
+                break;
+            }
+            if (value instanceof SimpleValue) {
+                targetCellsList = cells;
+                targetCellName = cellName;
+                break;
+            }
+        }
+        unprocessedCellsMap.remove(targetCellName);
+        return targetCellsList;
+    }
+
+    public List<BindData> buildCellData(Cell cell) {
+        return DataCompute.buildCellData(cell, this);
+    }
+
+    public void addReportCell(Cell newCell) {
+        boolean lazyAdd = report.addCell(newCell);
+    }
+
+    public void addCell(Cell newCell) {
+        addReportCell(newCell);
+        addUnprocessedCell(newCell);
+    }
+
+    public void addUnprocessedCell(Cell cell) {
+        String cellName = cell.getName();
+        List<Cell> cells = null;
+        if (unprocessedCellsMap.containsKey(cellName)) {
+            cells = unprocessedCellsMap.get(cellName);
+        } else {
+            cells = new ArrayList<>();
+            unprocessedCellsMap.put(cellName, cells);
+        }
+
+        int lastIdx = report.findSameLeftCell(cells, cell, 0);
+        if (lastIdx > -1 && lastIdx < cells.size() - 1) {
+            cells.add(lastIdx + 1, cell);
+        } else {
+            cells.add(cell);
+        }
+    }
+
+    public List<Map<String, Object>> getDatasetData(String name) {
+        List<Map<String, Object>> list = new ArrayList<>();
+        if (datasetMap.containsKey(name)) {
+            list.addAll(datasetMap.get(name).getData());
+        }
+        return list;
+    }
+
+    public Row getRow(int rowNumber) {
+        return report.getRow(rowNumber);
+    }
+
+    public Column getColumn(int columnNumber) {
+        return report.getColumn(columnNumber);
+    }
+
+    public void addBlankCell(Cell cell) {
+        cell.setBlankCell(true);
+        Row row = cell.getRow();
+        Column column = cell.getColumn();
+        Map<Column, Cell> cellMap = blankCellsMap.get(row);
+        if (cellMap == null) {
+            cellMap = new HashMap<>();
+            blankCellsMap.put(row, cellMap);
+        }
+        cellMap.put(column, cell);
+        addReportCell(cell);
+    }
+
+    public Cell getBlankCell(Row row, Column column) {
+        Map<Column, Cell> colCellMap = blankCellsMap.get(row);
+        if (colCellMap == null) {
+            return null;
+        }
+        Cell targetCell = colCellMap.get(column);
+        return targetCell;
+    }
+
+    public void removeBlankCell(Cell blankCell) {
+        Row row = blankCell.getRow();
+        Column col = blankCell.getColumn();
+        Map<Column, Cell> colCellMap = blankCellsMap.get(row);
+        colCellMap.remove(col);
+    }
+
+    public void putVariable(String key, Object value) {
+        variableMap.put(key, value);
+    }
+
+    public Object evalExpr(String expression) {
+        return new ElCompute().doCompute(expression);
+    }
+
+    public boolean isCellPocessed(String cellName) {
+        return !unprocessedCellsMap.containsKey(cellName);
+    }
+
+    public void addFillBlankRow(String cellName, Row row, int value) {
+        Map<Row, Integer> rowMap = new HashMap<>();
+        rowMap.put(row, value);
+        fillBlankRowsMap.put(cellName, rowMap);
+    }
+
+    public Object getVariable(String key) {
+        return variableMap.get(key);
+    }
+
+}

+ 31 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/ureport/build/DataCompute.java

@@ -0,0 +1,31 @@
+package jnpf.ureport.build;
+
+import com.google.common.collect.ImmutableMap;
+import jnpf.ureport.compute.DatasetValueCompute;
+import jnpf.ureport.compute.SimpleValueCompute;
+import jnpf.ureport.compute.ValueCompute;
+import jnpf.ureport.definition.value.Value;
+import jnpf.ureport.definition.value.ValueType;
+import jnpf.ureport.model.Cell;
+import lombok.Data;
+
+import java.util.List;
+import java.util.Map;
+
+@Data
+public class DataCompute {
+
+    private static Map<String, ValueCompute> valueComputesMap = ImmutableMap.of(
+            ValueType.simple.name(), new SimpleValueCompute(),
+            ValueType.dataset.name(), new DatasetValueCompute()
+    );
+
+    public static List<BindData> buildCellData(Cell cell, Context context) {
+        Value value = cell.getValue();
+        ValueCompute valueCompute = valueComputesMap.get(value.getType());
+        if (valueCompute == null) {
+            valueCompute = valueComputesMap.get(ValueType.simple);
+        }
+        return valueCompute.compute(cell, context);
+    }
+}

+ 15 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/ureport/build/Dataset.java

@@ -0,0 +1,15 @@
+package jnpf.ureport.build;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+import java.util.Map;
+
+
+@Setter
+@Getter
+public class Dataset {
+    private String name;
+    private List<Map<String, Object>> data;
+}

+ 34 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/ureport/build/DatasetUtils.java

@@ -0,0 +1,34 @@
+package jnpf.ureport.build;
+
+import com.google.common.collect.ImmutableMap;
+import jnpf.ureport.build.aggregate.*;
+import jnpf.ureport.definition.value.AggregateType;
+import jnpf.ureport.definition.value.DatasetValue;
+import jnpf.ureport.model.Cell;
+
+import java.util.List;
+import java.util.Map;
+
+public class DatasetUtils {
+
+    private static final Map<AggregateType, Aggregate> aggregates = ImmutableMap.of(
+            AggregateType.group, new GroupAggregate(),
+            AggregateType.select, new SelectAggregate(),
+            AggregateType.avg, new AvgAggregate(),
+            AggregateType.count, new CountAggregate(),
+            AggregateType.sum, new SumAggregate(),
+            AggregateType.min, new MinAggregate(),
+            AggregateType.max, new MaxAggregate(),
+            AggregateType.none, new NoneAggregate()
+    );
+
+
+    public static List<BindData> computeDatasetExpression(DatasetValue datasetValue, Cell cell, Context context) {
+        AggregateType type = datasetValue.getAggregate();
+        Aggregate aggregate = aggregates.get(type);
+        if (aggregate == null) {
+            aggregate = aggregates.get(AggregateType.select);
+        }
+        return aggregate.aggregate(datasetValue, cell, context);
+    }
+}

+ 238 - 0
jnpf-datareport-univer-model/src/main/java/jnpf/ureport/build/ReportBuilder.java

@@ -0,0 +1,238 @@
+package jnpf.ureport.build;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.google.common.collect.ImmutableList;
+import jnpf.univer.sheet.UniverSheetCellData;
+import jnpf.ureport.cell.CellBuilder;
+import jnpf.ureport.cell.down.DownExpandBuilder;
+import jnpf.ureport.cell.none.NoneExpandBuilder;
+import jnpf.ureport.cell.right.RightExpandBuilder;
+import jnpf.ureport.definition.Expand;
+import jnpf.ureport.definition.ReportDefinition;
+import jnpf.ureport.definition.value.*;
+import jnpf.ureport.model.Cell;
+import jnpf.ureport.model.Column;
+import jnpf.ureport.model.Report;
+import jnpf.ureport.model.Row;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+
+public class ReportBuilder {
+    public static final String DATASET = "dataset";
+    private final Map<Expand, CellBuilder> cellBuildersMap = new HashMap<>();
+
+    public ReportBuilder() {
+        cellBuildersMap.put(Expand.Down, new DownExpandBuilder());
+        cellBuildersMap.put(Expand.None, new NoneExpandBuilder());
+        cellBuildersMap.put(Expand.Right, new RightExpandBuilder());
+    }
+
+    public Report buildReport(ReportDefinition reportDefinition,Map<String, String> sortInMap) {
+        Report report = reportDefinition.newReport();
+        Map<String, Integer> fillBlankRowsMap = reportDefinition.getFillBlankRowsMap();
+        Map<String, Dataset> datasetMap = reportDefinition.getDatasetMap();
+        Context context = new Context(this, report, datasetMap);
+        List<Cell> cells = new ArrayList<>();
+        cells.add(report.getRootCell());
+        do {
+            buildCell(context, cells, fillBlankRowsMap,sortInMap);
+            cells = context.nextUnprocessedCells();
+        } while (cells != null);
+        doFillBlankRows(report, context);
+        return report;
+    }
+
+    public void buildCell(Context context, List<Cell> cells) {
+        buildCell(context, cells, new HashMap<>(), null);
+    }
+
+    public void buildCell(Context context, List<Cell> cells, Map<String, Integer> fillRowMap,Map<String, String> sortInMap) {
+        if (cells == null) {
+            cells = context.nextUnprocessedCells();
+        }
+        if (cells == null) {
+            return;
+        }
+        CellBuilder noneExpandBuilder = new NoneExpandBuilder();
+        for (int i = 0; i < cells.size(); i++) {
+            Cell cell = cells.get(i);
+            String sort="";
+            if (cell.getValue().getType().equals(DATASET)){
+                DatasetValue value = (DatasetValue) cell.getValue();
+                if (CollectionUtil.isNotEmpty(sortInMap)) {
+                        Set<String> strings = sortInMap.keySet();
+                        List<String> collect = strings.stream()
+                                .filter(value.getDatasetName()::equals).collect(Collectors.toList());
+                        if (CollectionUtil.isNotEmpty(collect)) {
+                            sort=collect.get(0);
+                            value.setSort(sort);
+                    }
+                }
+            }
+
+
+            List<BindData> dataList = context.buildCellData(cell);
+            cell.setProcessed(true);
+            int size = dataList.size();
+            Cell lastCell = cell;
+            if (size == 1) {
+                lastCell = noneExpandBuilder.buildCell(dataList, cell, context);
+            } else if (size > 1) {
+                CellBuilder cellBuilder = cellBuildersMap.get(cell.getExpand());
+                lastCell = cellBuilder.buildCell(dataList, cell, context);
+            }
+            boolean isLast = i == cells.size() - 1;
+            if (isLast && fillRowMap.get(cell.getName()) != null) {
+                int multiple = fillRowMap.get(cell.getName());
+                context.addFillBlankRow(lastCell.getName(), lastCell.getRow(), multiple);
+            }
+        }
+    }
+
+    private int resultCount(int total, int multiple, int num) {
+        int multipleNum = multiple * num;
+        if (multipleNum >= total) {
+            return multipleNum - total;
+        }
+        return resultCount(total, multiple, num + 1);
+    }
+
+    private void doFillBlankRows(Report report, Context context) {
+        Map<String, List<Cell>> cellsMap = report.getCellsMap();
+        Map<String, Map<Row, Integer>> map = context.getFillBlankRowsMap();
+        for (String key : map.keySet()) {
+            List<Cell> cells = cellsMap.get(key) != null ? cellsMap.get(key) : new ArrayList<>();
+            List<Row> newRowList = new ArrayList<>();
+            Map<Row, Integer> rowMap = map.get(key);
+            int total = cells.size();
+            for (Row row : rowMap.keySet()) {
+                int multiple = rowMap.get(row);
+                int size = resultCount(total, multiple, 1);
+                Row lastRow = findLastRow(row, report);
+                for (int i = 0; i < size; i++) {
+                    Row newRow = buildNewRow(lastRow, report);
+                    newRowList.add(newRow);
+                }
+                int rowNumber = lastRow.getRowNumber();
+                if (!newRowList.isEmpty()) {
+                    report.insertRows(rowNumber + 1, newRowList);
+                    newRowList.clear();
+                }
+            }
+        }
+    }
+
+    private Row findLastRow(Row row, Report report) {
+        List<Row> rows = report.getRows();
+        List<Cell> cells = row.getCells();
+        Row lastRow = row;
+        int span = 0;
+        for (Cell cell : cells) {
+            int rowSpan = cell.getRowSpan();
+            if (rowSpan < 2) {
+                continue;
+            }
+            if (span == 0) {
+                span = rowSpan;
+            } else if (rowSpan > span) {
+                span = rowSpan;
+            }
+        }
+        if (span > 1) {
+            int rowIndex = row.getRowNumber() - 1 + span - 1;
+            lastRow = rows.get(rowIndex);
+        }
+        return lastRow;
+    }
+
+    private Row buildNewRow(Row row, Report report) {
+        Row newRow = row.newRow();
+        List<Row> rows = report.getRows();
+        List<Column> columns = report.getColumns();
+        int start = -1;
+        int colSize = columns.size();
+        Map<Row, Map<Column, Cell>> rowMap = report.getRowColCellMap();
+        Map<Column, Cell> newCellMap = new HashMap<>();
+        rowMap.put(newRow, newCellMap);
+
+        Map<Column, Cell> colMap = rowMap.get(row);
+        for (int index = 0; index < colSize; index++) {
+            Column column = columns.get(index);
+            Cell currentCell = colMap.get(column);
+            if (currentCell == null) {
+                if (start == -1) {
+                    start = row.getRowNumber() - 2;
+                }
+                for (int i = start; i > -1; i--) {
+                    Row currentRow = rows.get(i);
+                    Map<Column, Cell> prevColMap = rowMap.get(currentRow);
+                    if (prevColMap == null) {
+                        continue;
+                    }
+                    if (prevColMap.containsKey(column)) {
+                        currentCell = prevColMap.get(column);
+                        break;
+                    }
+                }
+            }
+            if (currentCell == null) {
+                continue;
+            }
+//            int colSpan = currentCell.getColSpan();
+//            if (colSpan > 0) {
+//                colSpan--;
+//                index += colSpan;
+//            }
+//            int rowSpan = currentCell.getRowSpan();
+//            if (rowSpan > 1) {
+//                currentCell.setRowSpan(rowSpan + 1);
+//            } else {
+            Cell newCell = newBlankCell(currentCell, column, report);
+            newCell.setRow(newRow);
+            newRow.getCells().add(newCell);
+            newCellMap.put(newCell.getColumn(), newCell);
+//            }
+        }
+        return newRow;
+    }
+
+    private Cell newBlankCell(Cell cell, Column column, Report report) {
+        Cell newCell = new Cell();
+        Value value = cell.getValue();
+        newCell.setData(null);
+        if (value instanceof DatasetValue) {
+            DatasetValue datasetValue = (DatasetValue) value;
+            List<AggregateType> typeList = ImmutableList.of(AggregateType.sum, AggregateType.avg, AggregateType.min, AggregateType.max, AggregateType.count);
+            AggregateType aggregate = datasetValue.getAggregate();
+            if (typeList.contains(aggregate)) {
+                newCell.setData(0);
+            }
+        }
+        newCell.setColSpan(cell.getColSpan());
+        report.addLazyCell(newCell);
+        newCell.setName(cell.getName());
+        newCell.setColumn(column);
+        newCell.setStyleModel(cell.getStyleModel());
+        newCell.setZxing(cell.getZxing());
+        newCell.setCellData(cell.getCellData());
+        newCell.setSheetColumnData(cell.getSheetColumnData());
+        newCell.setSheetRowData(cell.getSheetRowData());
+        column.getCells().add(newCell);
+        Cell leftParent = cell.getLeftParentCell();
+        if (leftParent != null) {
+            newCell.setLeftParentCell(leftParent);
+            leftParent.addRowChild(newCell);
+        }
+        Cell topParent = cell.getTopParentCell();
+        if (topParent != null) {
+            newCell.setTopParentCell(topParent);
+            topParent.addColumnChild(newCell);
+        }
+        return newCell;
+    }
+
+}

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott