diff --git a/wmyun-framework/pom.xml b/wmyun-framework/pom.xml
index 1f91161..2e0740a 100644
--- a/wmyun-framework/pom.xml
+++ b/wmyun-framework/pom.xml
@@ -31,6 +31,7 @@
wmyun-spring-boot-starter-biz-tenant
wmyun-spring-boot-starter-biz-data-permission
wmyun-spring-boot-starter-biz-ip
+ wmyun-spring-boot-starter-word
wmyun-framework
diff --git a/wmyun-framework/wmyun-spring-boot-starter-word/pom.xml b/wmyun-framework/wmyun-spring-boot-starter-word/pom.xml
new file mode 100644
index 0000000..2185f10
--- /dev/null
+++ b/wmyun-framework/wmyun-spring-boot-starter-word/pom.xml
@@ -0,0 +1,89 @@
+
+
+
+ com.wmyun
+ wmyun-framework
+ ${revision}
+
+ 4.0.0
+ wmyun-spring-boot-starter-word
+ jar
+
+ ${project.artifactId}
+ Word 拓展
+
+
+
+ com.wmyun
+ wmyun-common
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+
+ com.wmyun
+ wmyun-spring-boot-starter-rpc
+ true
+
+
+
+
+ com.wmyun
+ wmyun-module-system-api
+ ${revision}
+
+
+
+
+ org.springframework
+ spring-web
+ provided
+
+
+
+ jakarta.servlet
+ jakarta.servlet-api
+ provided
+
+
+
+ com.google.guava
+ guava
+
+
+
+
+ com.wmyun
+ wmyun-spring-boot-starter-test
+ test
+
+
+
+
+ org.apache.poi
+ poi
+ 5.2.5
+
+
+
+
+ com.deepoove
+ poi-tl
+ 1.12.2
+
+
+
+ org.springframework
+ spring-expression
+ 5.3.18
+
+
+
+
diff --git a/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/config/DefaultConfig.java b/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/config/DefaultConfig.java
new file mode 100644
index 0000000..3f5fb0f
--- /dev/null
+++ b/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/config/DefaultConfig.java
@@ -0,0 +1,19 @@
+package com.wmyun.farmwork.word.config;
+
+import com.deepoove.poi.config.Configure;
+import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
+import com.wmyun.farmwork.word.core.model.constant.TagType;
+
+/**
+ * @Description: TODO
+ * @Date: 2025/3/1 11:27
+ * @Created: by ZZSLL
+ */
+
+public class DefaultConfig {
+ public static Configure def() {
+ return Configure.builder()
+ .addPlugin(TagType.LOOP_ROW_TABLE.getSign().charAt(0), new LoopRowTableRenderPolicy()).build();
+// .addPlugin(TagType.LOOP_COL_TABLE.getSign().charAt(0), new LoopColumnTableRenderPolicy());
+ }
+}
diff --git a/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/core/TemplateReplaceExecutor.java b/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/core/TemplateReplaceExecutor.java
new file mode 100644
index 0000000..12322b5
--- /dev/null
+++ b/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/core/TemplateReplaceExecutor.java
@@ -0,0 +1,60 @@
+package com.wmyun.farmwork.word.core;
+
+import com.deepoove.poi.XWPFTemplate;
+import com.deepoove.poi.config.Configure;
+import com.deepoove.poi.data.Pictures;
+import com.deepoove.poi.data.Texts;
+import com.deepoove.poi.data.style.Style;
+import com.wmyun.farmwork.word.config.DefaultConfig;
+import com.wmyun.farmwork.word.core.model.exec.TemplateExecDataModel;
+import com.wmyun.farmwork.word.core.model.type.TypeImage;
+import com.wmyun.farmwork.word.core.model.type.TypeText;
+import jakarta.validation.constraints.NotNull;
+import org.springframework.stereotype.Component;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * @Description: TODO
+ * @Date: 2025/3/1 11:52
+ * @Created: by ZZSLL
+ */
+
+@Component
+public class TemplateReplaceExecutor {
+ public String doReplace(@NotNull String absolutePath, TemplateExecDataModel data) {
+ return doReplace(absolutePath, data, DefaultConfig.def());
+ }
+
+ private String doReplace(@NotNull String absolutePath, TemplateExecDataModel data, Configure def) {
+ File wordFile = new File(absolutePath);
+ Map dataMap = new HashMap<>();
+ for (TypeText text : data.getText()) {
+ dataMap.put(text.getName(), Texts
+ .of(text.getValue()).create());
+ }
+ for (TypeImage image : data.getImage()) {
+ dataMap.put(image.getName(), Pictures
+ .of(image.getValue())
+ .size(image.getWidth(), image.getHeight())
+ .create());
+ }
+ XWPFTemplate word = XWPFTemplate.compile(absolutePath, def).render(dataMap);
+ String name = wordFile.getName();
+ String tmpDir = System.getProperty("java.io.tmpdir");
+ String output = tmpDir + File.separator + name;
+ try {
+ word.writeAndClose(new FileOutputStream(output));
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new RuntimeException(e);
+ }
+
+ return output;
+ }
+}
diff --git a/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/core/TemplateTagsGenerate.java b/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/core/TemplateTagsGenerate.java
new file mode 100644
index 0000000..f7a5c78
--- /dev/null
+++ b/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/core/TemplateTagsGenerate.java
@@ -0,0 +1,91 @@
+package com.wmyun.farmwork.word.core;
+
+import com.deepoove.poi.XWPFTemplate;
+import com.deepoove.poi.config.Configure;
+import com.deepoove.poi.template.ElementTemplate;
+import com.deepoove.poi.template.MetaTemplate;
+import com.deepoove.poi.template.run.RunTemplate;
+import com.wmyun.farmwork.word.config.DefaultConfig;
+import com.wmyun.farmwork.word.core.model.constant.TagType;
+import com.wmyun.farmwork.word.core.model.gen.TagsGenDataModel;
+import com.wmyun.farmwork.word.core.utils.WPUtils;
+import jakarta.validation.constraints.NotNull;
+import org.apache.poi.xwpf.usermodel.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @Description: 模板标签生成
+ * @Date: 2025/3/1 11:01
+ * @Created: by ZZSLL
+ */
+
+
+
+public class TemplateTagsGenerate {
+
+ public static List execAllTags(@NotNull String absolutePath) {
+ return execAllTags(absolutePath, DefaultConfig.def());
+ }
+
+
+ /**
+ * 获取文件中所有标签,如果是表格,获取表格中每一行标签
+ * @param absolutePath 文件路径
+ * @return List
+ */
+ public static List execAllTags(@NotNull String absolutePath, Configure conf) {
+
+ List results = new ArrayList<>();
+
+ XWPFTemplate template = XWPFTemplate.compile(absolutePath, conf);
+ Pattern pattern = Pattern.compile("\\[(.*?)\\]");
+
+ List list = template.getElementTemplates();
+ for (MetaTemplate metaTemplate : list) {
+ TagsGenDataModel result = new TagsGenDataModel();
+ if (metaTemplate instanceof ElementTemplate ele) {
+ String source = ele.getSource();
+ String tagName = ele.getTagName();
+ if (source.contains(TagType.PICTURE.getSign())) {
+ result.setType(TagType.PICTURE);
+ result.setName(tagName);
+ } else if (source.contains(TagType.LOOP_ROW_TABLE.getSign())) {
+ result.setType(TagType.LOOP_ROW_TABLE);
+ result.setName(tagName);
+ if (metaTemplate instanceof RunTemplate runTemplate) {
+ XWPFRun run = runTemplate.getRun();
+ XWPFTableCell tagCell = (XWPFTableCell) ((XWPFParagraph) run.getParent()).getBody();
+ XWPFTable table = tagCell.getTableRow().getTable();
+ int templateRowIndex = WPUtils.getTemplateRowIndex(tagCell, false);
+
+ XWPFTableRow row = table.getRow(templateRowIndex);
+ List fields = new ArrayList<>();
+ for (XWPFTableCell cell : row.getTableCells()) {
+ String text = cell.getText();
+
+ Matcher matcher = pattern.matcher(text);
+
+ while (matcher.find()) {
+ String colTag = matcher.group(1);
+ fields.add(colTag);
+ }
+ }
+ result.setFields(fields);
+ }
+ }
+
+ else {
+ result.setType(TagType.TEXT);
+ result.setName(tagName);
+ }
+ }
+ results.add(result);
+ }
+
+ return results;
+ }
+}
diff --git a/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/core/model/constant/TagType.java b/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/core/model/constant/TagType.java
new file mode 100644
index 0000000..f862a78
--- /dev/null
+++ b/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/core/model/constant/TagType.java
@@ -0,0 +1,30 @@
+package com.wmyun.farmwork.word.core.model.constant;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @Classname TagType
+ * @Description TODO
+ * @Date 2025/3/1 11:10
+ * @Created by violet
+ */
+
+@Getter
+@AllArgsConstructor
+public enum TagType {
+
+ TEXT("TEXT", ""),
+
+ PICTURE("PICTURE", "@"),
+
+// NEW_TABLE("NEW_TABLE", "#"),
+
+ LOOP_ROW_TABLE("LOOP_ROW_TABLE", "&");
+
+// LOOP_COL_TABLE("LOOP_COL_TABLE", "*");
+
+ private final String type;
+
+ private final String sign;
+}
diff --git a/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/core/model/exec/TemplateExecDataModel.java b/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/core/model/exec/TemplateExecDataModel.java
new file mode 100644
index 0000000..c3a5a97
--- /dev/null
+++ b/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/core/model/exec/TemplateExecDataModel.java
@@ -0,0 +1,23 @@
+package com.wmyun.farmwork.word.core.model.exec;
+
+import com.wmyun.farmwork.word.core.model.type.TypeImage;
+import com.wmyun.farmwork.word.core.model.type.TypeText;
+import lombok.*;
+
+import java.util.List;
+
+/**
+ * @Description: TODO
+ * @Date: 2025/3/1 11:02
+ * @Created: by @ZZSLL
+ */
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class TemplateExecDataModel {
+
+ private List text;
+
+ private List image;
+}
diff --git a/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/core/model/gen/TagsGenDataModel.java b/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/core/model/gen/TagsGenDataModel.java
new file mode 100644
index 0000000..14121b8
--- /dev/null
+++ b/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/core/model/gen/TagsGenDataModel.java
@@ -0,0 +1,34 @@
+package com.wmyun.farmwork.word.core.model.gen;
+
+import com.wmyun.farmwork.word.core.model.constant.TagType;
+import lombok.*;
+
+import java.util.List;
+
+/**
+ * @Description: 解析模板内所有标签,生成的DataModel,该数据将用于生成 com.wmyun.farmwork.word.core.model.exec.TemplateExecDataModel
+ * @Date: 2025/3/1 11:05
+ * @Created: by ZZSLL
+ */
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class TagsGenDataModel {
+
+ /**
+ * 数据类型 可选 文本、图片、 表格
+ */
+ private TagType type;
+
+ /**
+ * 标签名称
+ */
+ private String name;
+
+ /**
+ * 标签包含字段,如果 type为表格,fields为表格内字段
+ */
+ private List fields;
+
+}
diff --git a/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/core/model/type/TypeImage.java b/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/core/model/type/TypeImage.java
new file mode 100644
index 0000000..d2c78fd
--- /dev/null
+++ b/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/core/model/type/TypeImage.java
@@ -0,0 +1,50 @@
+package com.wmyun.farmwork.word.core.model.type;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * @Description: TODO
+ * @Date: 2025/3/1 14:12
+ * @Created: by ZZSLL
+ */
+
+@Data
+@AllArgsConstructor
+public class TypeImage {
+
+ /**
+ * 标签名称
+ */
+ private String name;
+
+ /**
+ * 标签值
+ */
+ private String value;
+
+ /**
+ * 图片格式
+ */
+ private String type;
+
+ /**
+ * 宽度
+ */
+ private Integer width;
+
+ /**
+ * 高度
+ */
+ private Integer height;
+
+ /**
+ * 当无法获取图片时展示的文字
+ */
+ private String altMeta;
+
+ /**
+ * 标签值类型,绝对路径、下载url
+ */
+ private String valueType;
+}
diff --git a/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/core/model/type/TypeTable.java b/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/core/model/type/TypeTable.java
new file mode 100644
index 0000000..39d75b1
--- /dev/null
+++ b/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/core/model/type/TypeTable.java
@@ -0,0 +1,27 @@
+package com.wmyun.farmwork.word.core.model.type;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: TODO
+ * @Date: 2025/3/1 14:19
+ * @Created: by ZZSLL
+ */
+
+@Data
+@AllArgsConstructor
+public class TypeTable {
+ /**
+ * 标签名称
+ */
+ private String name;
+
+ /**
+ * 标签值
+ */
+ private List