wip: bookmark replace
This commit is contained in:
parent
3ce85b2874
commit
4c5c10124b
@ -84,6 +84,11 @@
|
||||
<artifactId>spring-expression</artifactId>
|
||||
<version>5.3.18</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
@ -0,0 +1,139 @@
|
||||
package com.wmyun.farmwork.word.core;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.io.file.FileNameUtil;
|
||||
import com.wmyun.farmwork.word.core.enums.BookmarkType;
|
||||
import com.wmyun.farmwork.word.core.model.AbstractExData;
|
||||
import com.wmyun.farmwork.word.core.model.BookmarkReplaceDataModel;
|
||||
import com.wmyun.farmwork.word.core.model.ext.PictureExData;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.util.Units;
|
||||
import org.apache.poi.xwpf.usermodel.*;
|
||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBookmark;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Description: TODO
|
||||
* @Date: 2025/3/3 10:10
|
||||
* @Created: by ZZSLL
|
||||
*/
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class BookmarkExec {
|
||||
|
||||
public final static String tmpDir = System.getProperty("java.io.tmpdir") + File.separator;
|
||||
|
||||
public static File replace(List<BookmarkReplaceDataModel> data, byte[] word, File file) {
|
||||
Map<String, BookmarkReplaceDataModel> map = data.stream().collect(Collectors.toMap(BookmarkReplaceDataModel::getName, b -> b));
|
||||
try (XWPFDocument doc = new XWPFDocument(IoUtil.toStream(word))) {
|
||||
// 收集所有段落
|
||||
|
||||
// 1. 正文中的段落
|
||||
List<XWPFParagraph> allParagraphs = new ArrayList<>(doc.getParagraphs());
|
||||
|
||||
// 2. 正文中表格内的段落
|
||||
for (XWPFTable table : doc.getTables()) {
|
||||
for (XWPFTableRow row : table.getRows()) {
|
||||
for (XWPFTableCell cell : row.getTableCells()) {
|
||||
allParagraphs.addAll(cell.getParagraphs());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 页眉中的段落及页眉内表格中的段落
|
||||
for (XWPFHeader header : doc.getHeaderList()) {
|
||||
allParagraphs.addAll(header.getParagraphs());
|
||||
for (XWPFTable table : header.getTables()) {
|
||||
for (XWPFTableRow row : table.getRows()) {
|
||||
for (XWPFTableCell cell : row.getTableCells()) {
|
||||
allParagraphs.addAll(cell.getParagraphs());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 页脚中的段落及页脚内表格中的段落
|
||||
for (XWPFFooter footer : doc.getFooterList()) {
|
||||
allParagraphs.addAll(footer.getParagraphs());
|
||||
for (XWPFTable table : footer.getTables()) {
|
||||
for (XWPFTableRow row : table.getRows()) {
|
||||
for (XWPFTableCell cell : row.getTableCells()) {
|
||||
allParagraphs.addAll(cell.getParagraphs());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (XWPFParagraph paragraph : allParagraphs) {
|
||||
List<CTBookmark> bookmarkStartList = paragraph.getCTP().getBookmarkStartList();
|
||||
for (CTBookmark bookmark : bookmarkStartList) {
|
||||
String name = bookmark.getName();
|
||||
if (map.containsKey(name)) {
|
||||
List<XWPFRun> runs = paragraph.getRuns();
|
||||
XWPFRun run = null;
|
||||
int idx = 0;
|
||||
for (int i = 0; i < runs.size(); i++) {
|
||||
Node previousSibling = runs.get(i).getCTR().getDomNode().getPreviousSibling();
|
||||
if (previousSibling != null) {
|
||||
String nodeName = previousSibling.getNodeName();
|
||||
if ("w:bookmarkEnd".equals(nodeName)) {
|
||||
Node bookmarkStartNode = previousSibling.getPreviousSibling();
|
||||
if (bookmarkStartNode != null) {
|
||||
Node nameAttribute = bookmarkStartNode.getAttributes().getNamedItem("w:name");
|
||||
if (nameAttribute != null && name.equals(nameAttribute.getNodeValue())) {
|
||||
idx = i - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (idx >= 0 && idx < runs.size()) {
|
||||
run = runs.get(idx);
|
||||
} else {
|
||||
run = paragraph.createRun();
|
||||
}
|
||||
BookmarkReplaceDataModel model = map.get(name);
|
||||
BookmarkType type = model.getType();
|
||||
if (BookmarkType.TEXT.equals(type)) {
|
||||
run.setText(model.getValue());
|
||||
}
|
||||
if (BookmarkType.PICTURE.equals(type)) {
|
||||
AbstractExData extData = model.getExtData();
|
||||
if (extData instanceof PictureExData picture) {
|
||||
try {
|
||||
run.addPicture(new ByteArrayInputStream(picture.readAsByteArray()), XWPFDocument.PICTURE_TYPE_PNG, picture.getPictureName(), Units.toEMU(picture.getWidth()), Units.toEMU(picture.getHeight()));
|
||||
} catch (InvalidFormatException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File outFile = FileUtil.newFile(tmpDir + "gen/" + FileNameUtil.getName(file));
|
||||
File parentDir = outFile.getParentFile();
|
||||
if (!parentDir.exists()) {
|
||||
parentDir.mkdirs();
|
||||
}
|
||||
try (FileOutputStream out = new FileOutputStream(outFile)) {
|
||||
doc.write(out);
|
||||
}
|
||||
return outFile;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
package com.wmyun.farmwork.word.core;
|
||||
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import com.wmyun.farmwork.word.core.model.BookmarkQueryDataModel;
|
||||
import org.apache.poi.xwpf.usermodel.*;
|
||||
import org.apache.xmlbeans.impl.common.IOUtil;
|
||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBookmark;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @Description: TODO
|
||||
* @Date: 2025/3/3 9:47
|
||||
* @Created: by ZZSLL
|
||||
*/
|
||||
|
||||
@Component
|
||||
public class BookmarkQuery {
|
||||
|
||||
/**
|
||||
* 查询word文件中所有书签
|
||||
*/
|
||||
public static List<BookmarkQueryDataModel> queryAll(byte[] fileContent) {
|
||||
InputStream in = new ByteArrayInputStream(fileContent);
|
||||
Set<BookmarkQueryDataModel> results = new HashSet<>();
|
||||
List<CTBookmark> bookmarks = new ArrayList<>();
|
||||
try (XWPFDocument doc = new XWPFDocument(in)) {
|
||||
for (XWPFParagraph paragraph : doc.getParagraphs()) {
|
||||
bookmarks.addAll(paragraph.getCTP().getBookmarkStartList());
|
||||
}
|
||||
|
||||
for (XWPFTable table : doc.getTables()) {
|
||||
for (XWPFTableRow row : table.getRows()) {
|
||||
for (XWPFTableCell cell : row.getTableCells()) {
|
||||
for (XWPFParagraph para : cell.getParagraphs()) {
|
||||
bookmarks.addAll(para.getCTP().getBookmarkStartList());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (XWPFHeader header : doc.getHeaderList()) {
|
||||
for (XWPFParagraph para : header.getParagraphs()) {
|
||||
bookmarks.addAll(para.getCTP().getBookmarkStartList());
|
||||
}
|
||||
for (XWPFTable table : header.getTables()) {
|
||||
for (XWPFTableRow row : table.getRows()) {
|
||||
for (XWPFTableCell cell : row.getTableCells()) {
|
||||
for (XWPFParagraph para : cell.getParagraphs()) {
|
||||
bookmarks.addAll(para.getCTP().getBookmarkStartList());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (XWPFFooter footer : doc.getFooterList()) {
|
||||
for (XWPFParagraph para : footer.getParagraphs()) {
|
||||
bookmarks.addAll(para.getCTP().getBookmarkStartList());
|
||||
}
|
||||
for (XWPFTable table : footer.getTables()) {
|
||||
for (XWPFTableRow row : table.getRows()) {
|
||||
for (XWPFTableCell cell : row.getTableCells()) {
|
||||
for (XWPFParagraph para : cell.getParagraphs()) {
|
||||
bookmarks.addAll(para.getCTP().getBookmarkStartList());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
for (CTBookmark bookmark : bookmarks) {
|
||||
String name = bookmark.getName();
|
||||
results.add(new BookmarkQueryDataModel(name, null));
|
||||
}
|
||||
|
||||
return new ArrayList<>(results);
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package com.wmyun.farmwork.word.core.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @Classname BookmarkType
|
||||
* @Description TODO
|
||||
* @Date 2025/3/3 9:46
|
||||
* @Created by violet
|
||||
*/
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum BookmarkType {
|
||||
|
||||
TEXT("TEXT"),
|
||||
|
||||
PICTURE("PICTURE");
|
||||
|
||||
|
||||
private final String type;
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package com.wmyun.farmwork.word.core.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @Classname ImageProvideType
|
||||
* @Description TODO
|
||||
* @Date 2025/3/3 10:59
|
||||
* @Created by violet
|
||||
*/
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum PictureProvideDataType {
|
||||
|
||||
DOWNLOAD_URL("DOWNLOAD_URL"),
|
||||
|
||||
BASE64("BASE64"),
|
||||
|
||||
ABSOLUTE_PATH("ABSOLUTE_PATH");
|
||||
|
||||
private final String type;
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.wmyun.farmwork.word.core.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Description: 扩展数据
|
||||
* @Date: 2025/3/3 10:58
|
||||
* @Created: by ZZSLL
|
||||
*/
|
||||
|
||||
@Data
|
||||
public class AbstractExData {
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.wmyun.farmwork.word.core.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.wmyun.farmwork.word.core.enums.BookmarkType;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Description: 查询word文件中所有书签,返回值数据结构
|
||||
* @Date: 2025/3/3 9:44
|
||||
* @Created: by ZZSLL
|
||||
*/
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class BookmarkQueryDataModel {
|
||||
|
||||
private String name;
|
||||
|
||||
private BookmarkType type;
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.wmyun.farmwork.word.core.model;
|
||||
|
||||
import com.wmyun.farmwork.word.core.enums.BookmarkType;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Description: 书签替换数据类型
|
||||
* @Date: 2025/3/3 10:04
|
||||
* @Created: by ZZSLL
|
||||
*/
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class BookmarkReplaceDataModel {
|
||||
|
||||
private String name;
|
||||
|
||||
private BookmarkType type;
|
||||
|
||||
private String value;
|
||||
|
||||
private AbstractExData extData;
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package com.wmyun.farmwork.word.core.model.ext;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.wmyun.farmwork.word.core.enums.PictureProvideDataType;
|
||||
import com.wmyun.farmwork.word.core.model.AbstractExData;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* @Description: 图片扩展数据
|
||||
* @Date: 2025/3/3 10:58
|
||||
* @Created: by ZZSLL
|
||||
*/
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class PictureExData extends AbstractExData {
|
||||
private Integer width;
|
||||
|
||||
private Integer height;
|
||||
|
||||
private String pictureName;
|
||||
|
||||
private PictureProvideDataType dataType;
|
||||
|
||||
private String data;
|
||||
|
||||
@SneakyThrows
|
||||
public byte[] readAsByteArray() {
|
||||
if (PictureProvideDataType.BASE64.equals(dataType)) {
|
||||
return Base64.getDecoder().decode(data);
|
||||
}
|
||||
if (PictureProvideDataType.DOWNLOAD_URL.equals(dataType)) {
|
||||
return HttpUtil.downloadBytes(data);
|
||||
}
|
||||
if (PictureProvideDataType.ABSOLUTE_PATH.equals(dataType)) {
|
||||
return FileUtil.readBytes(data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.wmyun.farmwork.word.core.model.ext;
|
||||
|
||||
import com.wmyun.farmwork.word.core.model.AbstractExData;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Description: 文字扩展数据
|
||||
* @Date: 2025/3/3 11:14
|
||||
* @Created: by ZZSLL
|
||||
*/
|
||||
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class TextExData extends AbstractExData {
|
||||
|
||||
private Boolean bold;
|
||||
|
||||
private Boolean italic;
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
package com.wmyun.farmwork.word.config;
|
||||
package com.wmyun.farmwork.word.deprecated.config;
|
||||
|
||||
import com.deepoove.poi.config.Configure;
|
||||
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
|
||||
import com.wmyun.farmwork.word.core.model.constant.TagType;
|
||||
import com.wmyun.farmwork.word.deprecated.core.model.constant.TagType;
|
||||
|
||||
/**
|
||||
* @Description: TODO
|
||||
@ -10,6 +10,7 @@ import com.wmyun.farmwork.word.core.model.constant.TagType;
|
||||
* @Created: by ZZSLL
|
||||
*/
|
||||
|
||||
@Deprecated
|
||||
public class DefaultConfig {
|
||||
public static Configure def() {
|
||||
return Configure.builder()
|
@ -1,14 +1,13 @@
|
||||
package com.wmyun.farmwork.word.core;
|
||||
package com.wmyun.farmwork.word.deprecated.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 com.wmyun.farmwork.word.deprecated.config.DefaultConfig;
|
||||
import com.wmyun.farmwork.word.deprecated.core.model.exec.TemplateExecDataModel;
|
||||
import com.wmyun.farmwork.word.deprecated.core.model.type.TypeImage;
|
||||
import com.wmyun.farmwork.word.deprecated.core.model.type.TypeText;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@ -16,7 +15,6 @@ import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@ -26,6 +24,7 @@ import java.util.Map;
|
||||
*/
|
||||
|
||||
@Component
|
||||
@Deprecated
|
||||
public class TemplateReplaceExecutor {
|
||||
public static String doReplace(@NotNull String absolutePath, TemplateExecDataModel data) {
|
||||
return doReplace(absolutePath, data, DefaultConfig.def());
|
@ -1,14 +1,14 @@
|
||||
package com.wmyun.farmwork.word.core;
|
||||
package com.wmyun.farmwork.word.deprecated.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 com.wmyun.farmwork.word.deprecated.config.DefaultConfig;
|
||||
import com.wmyun.farmwork.word.deprecated.core.model.constant.TagType;
|
||||
import com.wmyun.farmwork.word.deprecated.core.model.gen.TagsGenDataModel;
|
||||
import com.wmyun.farmwork.word.deprecated.core.utils.WPUtils;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import org.apache.poi.xwpf.usermodel.*;
|
||||
|
||||
@ -25,6 +25,7 @@ import java.util.regex.Pattern;
|
||||
|
||||
|
||||
|
||||
@Deprecated
|
||||
public class TemplateTagsGenerate {
|
||||
|
||||
public static List<TagsGenDataModel> execAllTags(@NotNull String absolutePath) {
|
@ -1,4 +1,4 @@
|
||||
package com.wmyun.farmwork.word.core.model.constant;
|
||||
package com.wmyun.farmwork.word.deprecated.core.model.constant;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
@ -12,6 +12,7 @@ import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
@Deprecated
|
||||
public enum TagType {
|
||||
|
||||
TEXT("TEXT", ""),
|
@ -1,7 +1,7 @@
|
||||
package com.wmyun.farmwork.word.core.model.exec;
|
||||
package com.wmyun.farmwork.word.deprecated.core.model.exec;
|
||||
|
||||
import com.wmyun.farmwork.word.core.model.type.TypeImage;
|
||||
import com.wmyun.farmwork.word.core.model.type.TypeText;
|
||||
import com.wmyun.farmwork.word.deprecated.core.model.type.TypeImage;
|
||||
import com.wmyun.farmwork.word.deprecated.core.model.type.TypeText;
|
||||
import lombok.*;
|
||||
|
||||
import java.util.List;
|
||||
@ -15,6 +15,7 @@ import java.util.List;
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Deprecated
|
||||
public class TemplateExecDataModel {
|
||||
|
||||
private List<TypeText> text;
|
@ -1,6 +1,6 @@
|
||||
package com.wmyun.farmwork.word.core.model.gen;
|
||||
package com.wmyun.farmwork.word.deprecated.core.model.gen;
|
||||
|
||||
import com.wmyun.farmwork.word.core.model.constant.TagType;
|
||||
import com.wmyun.farmwork.word.deprecated.core.model.constant.TagType;
|
||||
import lombok.*;
|
||||
|
||||
import java.util.List;
|
||||
@ -14,6 +14,7 @@ import java.util.List;
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Deprecated
|
||||
public class TagsGenDataModel {
|
||||
|
||||
/**
|
@ -1,4 +1,4 @@
|
||||
package com.wmyun.farmwork.word.core.model.type;
|
||||
package com.wmyun.farmwork.word.deprecated.core.model.type;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
@ -11,6 +11,7 @@ import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@Deprecated
|
||||
public class TypeImage {
|
||||
|
||||
/**
|
@ -1,4 +1,4 @@
|
||||
package com.wmyun.farmwork.word.core.model.type;
|
||||
package com.wmyun.farmwork.word.deprecated.core.model.type;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
@ -14,6 +14,7 @@ import java.util.Map;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@Deprecated
|
||||
public class TypeTable {
|
||||
/**
|
||||
* 标签名称
|
@ -1,4 +1,4 @@
|
||||
package com.wmyun.farmwork.word.core.model.type;
|
||||
package com.wmyun.farmwork.word.deprecated.core.model.type;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
@ -11,6 +11,7 @@ import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@Deprecated
|
||||
public class TypeText {
|
||||
|
||||
/**
|
@ -1,4 +1,4 @@
|
||||
package com.wmyun.farmwork.word.core.utils;
|
||||
package com.wmyun.farmwork.word.deprecated.core.utils;
|
||||
|
||||
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
|
@ -0,0 +1,126 @@
|
||||
销售合同
|
||||
Sales Contract
|
||||
Договор купли-продажи
|
||||
|
||||
合同号Contract Договор No.:
|
||||
日期 Date Дата:
|
||||
地点The place Место:
|
||||
|
||||
卖方The Seller Продавец:
|
||||
Ensign Heavy Industries Co., Ltd.
|
||||
Инсайн Хеви Индастриз Ко., Лтд
|
||||
Add: No. 1567, Ensign Street, and Economic Development Zone,
|
||||
Changle, Weifang, Shandong, China
|
||||
Адрес: № 1567, Инcайн Стрит энд Экономик Девелопмент Зоун,
|
||||
Чанле, Вейфань, Шаньдунь, Китай
|
||||
Tel: +86-536-6295117 Fax: +86-536-6298797
|
||||
Тел: +86 536 6296117, факс +86 536 6298797
|
||||
Contact: Eda
|
||||
Контактное лицо: Эда
|
||||
Email: eda@ensignhi.com
|
||||
Адрес эл.почты: eda@ensignhi.com
|
||||
|
||||
买方The Buyer Покупатель:
|
||||
ТОО "Atameken-Energy"
|
||||
|
||||
Add/Адрес: КАЗАХСТАН, ТУРКЕСТАНСКАЯ обл, ТУРКЕСТАН г, ТУРКЕСТАН г, УЛИЦА А.ЮСУПОВ ул, дом 160
|
||||
|
||||
Contact / Контактное лицо: БОЛАТ НАГЫМЖАН
|
||||
|
||||
本合同由双方订立,根据本合同规定的条款,卖方同意出售,买方同意购买下列货物。
|
||||
This contract is made by and between the Seller and Buyer, whereby the Seller agrees to sell and the Buyer agrees to buy the under mentioned commodity according to the terms and conditions stipulated below:
|
||||
Настоящий договор заключен между Продавцом и Покупателем, согласно чему, Продавец продает, а Покупатель покупает нижеуказанный товар, в соответствии с условиями и сроками, определенными ниже:
|
||||
|
||||
商品名称及价格 Commodity, Quantity, Unit price and Total Value:
|
||||
Товар, количество, цена за единицу, общая стоимость
|
||||
Name, range, quantity, and price of Goods for every lot, as well as delivery period will be specified in
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
No.
|
||||
п/п
|
||||
PART NO.
|
||||
Номер детали
|
||||
PART NAME
|
||||
Наименование детали
|
||||
QTY
|
||||
Кол-во
|
||||
Unit Price
|
||||
Цена за ед.
|
||||
Total price
|
||||
Цена итого
|
||||
|
||||
|
||||
|
||||
|
||||
FCA Ensign factory in CNY{{&table}}
|
||||
[index]
|
||||
[m_code]
|
||||
[m_name]
|
||||
[m_qty]
|
||||
[m_unit_price]
|
||||
[m_amount]
|
||||
TOTAL QUANTITY: {{total_qty}}
|
||||
212Pcs
|
||||
TOTAL AMOUNT: {{total_amount}}
|
||||
CNY10000
|
||||
SAY TOTAL:CHINESE YUAN TENTHOUSAND ONLY.
|
||||
|
||||
包装Packing Упаковка: 装于箱内Packed in boxes Упаковано в коробки
|
||||
装运期Time of Shipment Время отгрузки: 2025年3月Before in March. 2025,
|
||||
装运港Port of Loading Пункт отгрузки: 中国 英轩工厂 Port,ChinaФабрика ENSIGN, Китай
|
||||
目的港Port of Destination Пункт назначения: 哈萨克斯坦,突厥斯坦 Turkestan Port, KazakhstanРусский Тур
|
||||
付款方式Payment Условия оплаты:
|
||||
Free given spare parts along with the purchasing machines.
|
||||
Бесплатно предоставляем запасные части вместе с приобретаемой техникой.
|
||||
合同有效期Expiry Date of the Contract Срок действия договора/срок возврата аванса:
|
||||
2025年5月30日 May 30th, 2025
|
||||
|
||||
货物所有权转移Transfer of the goods ownership Передача товара в собственность:
|
||||
买方付清全部货款后,货物所有权转移给买方;如果买方没有付清全部货款,卖方保留对货物的全部所有权。
|
||||
The ownership of the goods shall be transferred to the buyer after the buyer pays back the total contract value. The seller retains the full ownership of the goods if the buyer doesn't pay back the total contract value.
|
||||
Передача товара в собственность Покупателю произойдет после полной оплаты Покупателем стоимости договора. Право собственности на товар сохраняется за Продавцом в случае, если Покупатель не выплачивает полную стоимость договора.
|
||||
9.不可抗力Force Majeure Форс-мажор:
|
||||
卖方由于罢工、火灾、地震、暴动、爆炸、政府行为等不可抗力事故,未能在合同规定期限内装货或不能交货,则不承担责任,卖方应立即以传真通知买方,如果买方提出要求,卖方应以挂号函件向买方提供由中国国际贸易促进委员会或有关机构出具的证明,证明上述事由的存在。
|
||||
The Seller shall not be held responsible if they, owing to force majeure cause, such as Act of God, strike, riot, civil commotion, breakdown of machinery, fire or any other causes beyond Seller's control, fail to make delivery within the time stipulated in the Contract or cannot deliver the goods. However in such cases, the Seller shall inform the Buyer immediately by fax and if it is requested by the Buyer, shall also deliver to the Buyer by registered letter, a certificate attesting the existence of such a cause issued by the China Council for the Promotion of International Trade or by a competent authority.
|
||||
Продавец не несет ответственности за события, происходящие вследствие форс-мажора, если таковые происходят: стихийные бедствия, забастовки, мятежи, гражданские волнения, выход из строя оборудования, пожар или другие события, выходящие за рамки контроля Продавца, и приведшие к нарушению сроков поставок в периоды, оговоренные Договором, либо к невозможности поставки Товара. Однако, о всех таких случаях Продавец незамедлительно информирует Покупателя по факсу и, если это требуется Покупателю, официальным письмом, справкой, подтверждающей наступление таких событий, заверенной китайским консулом по международной торговле или другим компетентным органом.
|
||||
|
||||
10.异议和索赔Discrepancy and Claim Несоответствия и претензии:
|
||||
(1)外观质量和数量等可目视检查的不符或缺失,买方需在货物到达目的港后10个工作日内提报卖方,产品潜在缺陷,买方需在货物到港后30个工作日内凭卖方认可的权威机构出具的检测报告提报卖方,未经卖方同意,买方不得销售或使用该类产品。
|
||||
(1) The visual survey of any discrepancy or deficiency such as apparent quality and quantity should be reported to the seller within 10 working days from the date of goods arrival at the destination port, while for the latent defects of goods, an Inspection Report issued by an approved authority institution by the Seller should be sent to the Seller within 30 working days from the date of goods arrival at the destination port. The defective goods which have not been approved by the Seller should not be sold or used.
|
||||
(1) Выявленные при визуальном осмотре несоответствия и дефекты, как в качестве, так и в количестве, должны быть предоставлены в форме отчета Продавцу в течение 10 рабочих дней в даты поступления товара в пункт назначения, в то время отчет по скрытым дефектам товара, выданный уполномоченным государством учреждением, должен быть отправлен Продавцу по электронной почте в течение 30 дней с даты поступления товара в пункт назначения. Оборудование с дефектами не может быть продано или использовано без разрешения Продавца.
|
||||
(2) 卖方向买方提供制造商提供的所有质保。装载机质保期为提单日起24个月,经销商销售日起18个月,装载机开始运行起2000个工作小时,以先到者为准
|
||||
(2)The Seller provides the Buyer all the warranties provided by the factory-manufacturer. Wheel loader warranty period is 24 months since date of B/L, 18 months since date of sale by the dealer, 2000 working hours since the loader starts to be operated,subject to whichever comes first.
|
||||
(2) Продавец обеспечивает Покупателю все гарантии, предоставленные заводом-производителем. Гарантийный период составляет 24 месяца с даты получения предоплаты, 18 месяцев с даты продажи дилером, 2000 мото/часов с момента запуска в работу, в зависимости от того, что наступает раньше.
|
||||
|
||||
11.仲裁Arbitration Арбитраж:
|
||||
凡因执行本合同和有关本合同所发生的一切争执,双方应协商解决,如果协商不能解决,应提交位于北京的中国国际经济贸易仲裁委员会,根据其仲裁规则进行仲裁,仲裁裁决是终局的,对双方均有约束力,除非另有规定外,仲裁费用均由败诉方负担。本合同适用中国法律。
|
||||
All disputes arising from the execution of, or in connection with this Contract, shall be settled through negotiation. In case no settlement can be reached through negotiation, the case shall then be submitted to the China International Economic and Trade Arbitration Commission, Beijing, for arbitration in accordance with the Commission's Rules of Procedure. The award rendered by the Commission shall be final and binding on bothparties. The fees for arbitration shall be borne by the losing party unless otherwise awarded. This contract issigned as to Chinese laws.
|
||||
Все споры, возникающие при исполнении или в связи с настоящим Контрактом, должны решаться путемпереговоров. В случае невозможности урегулирования спора путем переговоров, дело передается вКитайскую международную экономическую и торговую арбитражную комиссию, Пекин, для арбитража всоответствии с Правилами процедуры Комиссии. Решение, вынесенное Комиссией, являетсяокончательным и обязательным для обеих сторон. Арбитражные сборы несет проигравшая сторона, если не принято иное решение. Настоящий договор подписан в соответствии с законодательством Китая.
|
||||
|
||||
12.本合同采用中英俄文书写,经双方签字后生效,传真件或扫描副本有效,如若中英俄文有歧义,则以中文为准。双方对本合同所有内容有保密义务,不得以任何形式泄露给第三方。任何一方在未取得对方书面同意前,无权将本合同规定之权利义务转让给第三方。本合同所有附件属于合同的组成部分,与本合同具有同等法律效力。
|
||||
This appendix is made in Chinese English and Russian becomes effective as soon as it is signed by both parties. Fax copies and scanned originals of the docs hold the same force. And if any dispute or miscellaneous on language here determinate that Chinese version is predominate authentic. Both parties shall be responsible to keep all the information under this contract confident and cannot reveal to any third party in any manner. Neither party is entitled to transfer its right and obligation under this Contract to a third party before obtaining a written consent from the other party. All appendixes to the Contract shall form an integral part of the Contract and have the same effectiveness as the contract。
|
||||
Настоящее приложение составлено на китайском английском и русском языках и вступает в силу с момента его подписания обеими сторонами. Факсимильные копии и сканы оригиналов документов имеют такую же силу. И если возникнет спор или разногласие по поводу языка, здесь определяется, что китайская версия является преобладающей аутентичной. Обе стороны несут ответственность за сохранение всей информации по настоящему договору в тайне и не могут раскрывать ее третьим лицам каким-либо образом. Ни одна из сторон не имеет права передавать свои права и обязательства по настоящему Контракту третьей стороне до получения письменного согласия другой стороны. Все приложения к контракту являются его неотъемлемой частью и имеют такую же силу, как и контракт.
|
||||
13、卖方银行信息 The Seller's Bank Information Банковские реквизиты
|
||||
本合同项下款项必须付到以下银行账户:
|
||||
Payments under this contract must be paid to the following bank account:
|
||||
Платежи по настоящему договору производятся по следующим банковским реквизитам:
|
||||
Beneficiary Получатель: ENSIGN HEAVY INDUSTRIES CO., LTD.
|
||||
Address Адрес: No.1567, Ensign Street, Economic Development Zone, Changle, Weifang, Shandong, China.
|
||||
Tel: +86-536-6298882 Fax:+86-536-6298797
|
||||
Bank Name Наименование банка : CHINA ZHESHANG BANK Китайский Zhe Shang Bank
|
||||
Bank Address Адрес банка: NO.288 Qingchun Road,Hangzhou City,Zhejiang Province,China
|
||||
№ 288 Цинчунь, город Ханчжоу, провинция Чжэцзян, Китай
|
||||
Swift Code: ZJCBCN2N
|
||||
Account Number: 4580000010120100081585
|
||||
以上任何银行信息的变更,以卖方传真通知为准。
|
||||
Any changes of the above bank information shall be subject to the seller's fax notice only.
|
||||
Все изменения банковских реквизитов допускаются только при условии направления Продавцом уведомления по факсу.
|
||||
|
||||
卖方 买方
|
||||
The Seller The Buyer
|
||||
Продавец: ________________ Покупатель : ______
|
||||
|
||||
供方盖章
|
@ -0,0 +1,38 @@
|
||||
package com.wmyun.module.infra.controller.admin.word;
|
||||
|
||||
import com.wmyun.farmwork.word.core.model.BookmarkQueryDataModel;
|
||||
import com.wmyun.farmwork.word.core.model.BookmarkReplaceDataModel;
|
||||
import com.wmyun.farmwork.word.deprecated.core.model.gen.TagsGenDataModel;
|
||||
import com.wmyun.framework.common.pojo.CommonResult;
|
||||
import com.wmyun.module.infra.service.file.WordBookmarkService;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @Description: TODO
|
||||
* @Date: 2025/3/3 9:36
|
||||
* @Created: by ZZSLL
|
||||
*/
|
||||
|
||||
@Tag(name = "管理后台 - Word bookmark替换")
|
||||
@RestController
|
||||
@RequestMapping("/infra/word/bookmark")
|
||||
public class WordBookmarkController {
|
||||
|
||||
@Autowired
|
||||
private WordBookmarkService service;
|
||||
|
||||
@PostMapping("/file/{fileId}")
|
||||
public CommonResult<Set<String>> requestAllBookmarks(@PathVariable("fileId") String fileId) {
|
||||
return CommonResult.success(service.queryAllBookmarks(fileId));
|
||||
}
|
||||
|
||||
@PostMapping("/file/{fileId}/generate")
|
||||
public CommonResult<Object> doGenerate(@PathVariable("fileId") String fileId, @RequestBody List<BookmarkReplaceDataModel> data) {
|
||||
return CommonResult.success(service.replaceBookmarkWithContent(fileId, data));
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package com.wmyun.module.infra.controller.admin.word;
|
||||
|
||||
import com.wmyun.farmwork.word.core.model.exec.TemplateExecDataModel;
|
||||
import com.wmyun.farmwork.word.core.model.gen.TagsGenDataModel;
|
||||
import com.wmyun.farmwork.word.deprecated.core.model.exec.TemplateExecDataModel;
|
||||
import com.wmyun.farmwork.word.deprecated.core.model.gen.TagsGenDataModel;
|
||||
import com.wmyun.framework.common.pojo.CommonResult;
|
||||
import com.wmyun.module.infra.service.file.WordTemplateTagService;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
@ -31,6 +31,8 @@ public interface FileService {
|
||||
*/
|
||||
String createFile(String name, String path, byte[] content);
|
||||
|
||||
FileDO createFileDO(String name, String path, byte[] content);
|
||||
|
||||
/**
|
||||
* 创建文件
|
||||
*
|
||||
|
@ -69,6 +69,36 @@ public class FileServiceImpl implements FileService {
|
||||
return url;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public FileDO createFileDO(String name, String path, byte[] content) {
|
||||
// 计算默认的 path 名
|
||||
String type = FileTypeUtils.getMineType(content, name);
|
||||
if (StrUtil.isEmpty(path)) {
|
||||
path = FileUtils.generatePath(content, name);
|
||||
}
|
||||
// 如果 name 为空,则使用 path 填充
|
||||
if (StrUtil.isEmpty(name)) {
|
||||
name = path;
|
||||
}
|
||||
|
||||
// 上传到文件存储器
|
||||
FileClient client = fileConfigService.getMasterFileClient();
|
||||
Assert.notNull(client, "客户端(master) 不能为空");
|
||||
String url = client.upload(content, path, type);
|
||||
|
||||
// 保存到数据库
|
||||
FileDO file = new FileDO();
|
||||
file.setConfigId(client.getId());
|
||||
file.setName(name);
|
||||
file.setPath(path);
|
||||
file.setUrl(url);
|
||||
file.setType(type);
|
||||
file.setSize(content.length);
|
||||
fileMapper.insert(file);
|
||||
return file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long createFile(FileCreateReqVO createReqVO) {
|
||||
FileDO file = BeanUtils.toBean(createReqVO, FileDO.class);
|
||||
|
@ -0,0 +1,20 @@
|
||||
package com.wmyun.module.infra.service.file;
|
||||
|
||||
import com.wmyun.farmwork.word.core.model.BookmarkReplaceDataModel;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @Classname WordBookmarkService
|
||||
* @Description TODO
|
||||
* @Date 2025/3/3 9:38
|
||||
* @Created by violet
|
||||
*/
|
||||
|
||||
public interface WordBookmarkService {
|
||||
|
||||
Set<String> queryAllBookmarks(String fileId);
|
||||
|
||||
Long replaceBookmarkWithContent(String fileId, List<BookmarkReplaceDataModel> data);
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package com.wmyun.module.infra.service.file;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import com.wmyun.farmwork.word.core.BookmarkExec;
|
||||
import com.wmyun.farmwork.word.core.BookmarkQuery;
|
||||
import com.wmyun.farmwork.word.core.model.BookmarkQueryDataModel;
|
||||
import com.wmyun.farmwork.word.core.model.BookmarkReplaceDataModel;
|
||||
import com.wmyun.module.infra.dal.dataobject.file.FileDO;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Description: TODO
|
||||
* @Date: 2025/3/3 9:38
|
||||
* @Created: by ZZSLL
|
||||
*/
|
||||
|
||||
@Service
|
||||
public class WordBookmarkServiceImpl implements WordBookmarkService {
|
||||
|
||||
@Autowired
|
||||
private FileService fileService;
|
||||
|
||||
@Autowired
|
||||
private FilePreviewService previewService;
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public Set<String> queryAllBookmarks(String fileId) {
|
||||
FileDO fileDO = previewService.queryFileInfoByFileId(fileId);
|
||||
return BookmarkQuery.queryAll(fileService.getFileContent(fileDO.getConfigId(), fileDO.getPath())).stream().map(BookmarkQueryDataModel::getName).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public Long replaceBookmarkWithContent(String fileId, List<BookmarkReplaceDataModel> data) {
|
||||
FileDO fileDO = previewService.queryFileInfoByFileId(fileId);
|
||||
byte[] content = fileService.getFileContent(fileDO.getConfigId(), fileDO.getPath());
|
||||
File file = FileUtil.newFile(BookmarkExec.tmpDir + fileDO.getName());
|
||||
FileUtil.writeBytes(content, file);
|
||||
File outputFile = BookmarkExec.replace(data, content, file);
|
||||
return fileService.createFileDO(outputFile.getName(), outputFile.getAbsolutePath(), FileUtil.readBytes(outputFile)).getId();
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package com.wmyun.module.infra.service.file;
|
||||
|
||||
import com.wmyun.farmwork.word.core.model.exec.TemplateExecDataModel;
|
||||
import com.wmyun.farmwork.word.core.model.gen.TagsGenDataModel;
|
||||
import com.wmyun.farmwork.word.deprecated.core.model.exec.TemplateExecDataModel;
|
||||
import com.wmyun.farmwork.word.deprecated.core.model.gen.TagsGenDataModel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
package com.wmyun.module.infra.service.file;
|
||||
|
||||
import com.wmyun.farmwork.word.core.TemplateReplaceExecutor;
|
||||
import com.wmyun.farmwork.word.core.TemplateTagsGenerate;
|
||||
import com.wmyun.farmwork.word.core.model.exec.TemplateExecDataModel;
|
||||
import com.wmyun.farmwork.word.core.model.gen.TagsGenDataModel;
|
||||
import com.wmyun.farmwork.word.deprecated.core.TemplateReplaceExecutor;
|
||||
import com.wmyun.farmwork.word.deprecated.core.TemplateTagsGenerate;
|
||||
import com.wmyun.farmwork.word.deprecated.core.model.exec.TemplateExecDataModel;
|
||||
import com.wmyun.farmwork.word.deprecated.core.model.gen.TagsGenDataModel;
|
||||
import com.wmyun.module.infra.dal.dataobject.file.FileDO;
|
||||
import com.wmyun.module.infra.framework.file.core.client.FileClient;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
Loading…
Reference in New Issue
Block a user