Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
D
dcs-doc-expand
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
INET-TWO
server
dcs-doc-expand
Commits
7988a858
Commit
7988a858
authored
Aug 13, 2024
by
wangyangyang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
调整
parent
5caa6483
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
1083 additions
and
391 deletions
+1083
-391
DocumentEvent.java
...src/main/java/com/yonde/dcs/core/event/DocumentEvent.java
+9
-0
DocBeforeCreateEvent.java
.../java/com/yonde/dcs/core/events/DocBeforeCreateEvent.java
+256
-256
ProcessDataUtils.java
...main/java/com/yonde/dcs/core/events/ProcessDataUtils.java
+135
-135
ExtDxDocumentServiceImpl.java
...cs/core/service/impl/expand/ExtDxDocumentServiceImpl.java
+12
-0
WordMarkUtil.java
...e/src/main/java/com/yonde/dcs/core/util/WordMarkUtil.java
+671
-0
No files found.
dcs-doc-expand-core/src/main/java/com/yonde/dcs/core/event/DocumentEvent.java
0 → 100644
View file @
7988a858
package
com
.
yonde
.
dcs
.
core
.
event
;
/**
* @author wyy
* @date 2024-8-13 10:17
* @describe
*/
public
class
DocumentEvent
{
}
dcs-doc-expand-core/src/main/java/com/yonde/dcs/core/events/DocBeforeCreateEvent.java
View file @
7988a858
//package com.yonde.dcs.core.events;
//
//
//import cn.hutool.core.io.FileUtil;
//import cn.hutool.extra.spring.SpringUtil;
//import com.alibaba.fastjson.JSONObject;
//import com.yonde.dcs.common.vo.ExtInterfaceInfoLinkVO;
//import com.yonde.dcs.core.constants.Constants;
//import com.yonde.dcs.core.factory.InternalInterfaceUtils;
//import com.yonde.dcs.core.factory.TechnicalFileUtils;
//import com.yonde.dcs.core.service.ExtDocService;
//import com.yonde.dcs.core.util.ExtDocUtil;
//import com.yonde.dcs.core.util.FileUtils;
//import com.yonde.dcs.core.word.ImportWordService;
//import com.yonde.dcs.document.common.entity.vo.DxDocumentVO;
//import com.yonde.dex.basedata.exception.DxBusinessException;
//import com.yonde.dex.dao.events.BusinessEventType;
//import com.yonde.dex.dao.events.DxEvent;
//import com.yonde.dex.dao.events.DxEventListener;
//import com.yonde.dex.dao.events.DxEventWrap;
//import com.yonde.dex.dfs.vo.ObjFileLinkVO;
//import com.yonde.dex.wfc.common.vo.DxWfProcessInfoVO;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.collections.CollectionUtils;
//import org.apache.commons.lang3.ObjectUtils;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Component;
//
//import java.io.File;
//import java.io.FileInputStream;
//import java.io.IOException;
//import java.io.InputStream;
//import java.lang.reflect.Method;
//import java.util.ArrayList;
//import java.util.Arrays;
//import java.util.List;
//
///**
// * @author xfchai
// * @ClassName DocBeforeCreateEvent.java
// * @Description 保存文档之前的操作事件
// * @createTime 2021/11/15 14:29:00
// */
//@Component
//@Slf4j
//@DxEvent
//public class DocBeforeCreateEvent {
// //word模板路径
// public static final String PATH = Constants.MTEMPLATE_ABSOLUTE_PATH;
// public static final String DOC_END_WITH = ".doc";
// public static final String DOCX_END_WITH = ".docx";
// @Autowired
// private ExtDocService extDocService;
// @Autowired
// private ImportWordService importWordService;
// @Autowired
// TechnicalFileUtils technicalFileUtils;
// @Autowired
// private ProcessDataUtils processDataUtils;
// @Autowired
// private ExtDocUtil extDocUtil;
//
// @DxEventListener(value = DxDocumentVO.class, eventType = BusinessEventType.BEFORE_CREATE, order = 1)
// public void createDocListener(List<DxEventWrap<DxDocumentVO>> events) {
// events.forEach(e -> {
package
com
.
yonde
.
dcs
.
core
.
events
;
import
cn.hutool.core.io.FileUtil
;
import
cn.hutool.extra.spring.SpringUtil
;
import
com.alibaba.fastjson.JSONObject
;
import
com.yonde.dcs.common.vo.ExtInterfaceInfoLinkVO
;
import
com.yonde.dcs.core.constants.Constants
;
import
com.yonde.dcs.core.factory.InternalInterfaceUtils
;
import
com.yonde.dcs.core.factory.TechnicalFileUtils
;
import
com.yonde.dcs.core.service.ExtDocService
;
import
com.yonde.dcs.core.util.ExtDocUtil
;
import
com.yonde.dcs.core.util.FileUtils
;
import
com.yonde.dcs.core.word.ImportWordService
;
import
com.yonde.dcs.document.common.entity.vo.DxDocumentVO
;
import
com.yonde.dex.basedata.exception.DxBusinessException
;
import
com.yonde.dex.dao.events.BusinessEventType
;
import
com.yonde.dex.dao.events.DxEvent
;
import
com.yonde.dex.dao.events.DxEventListener
;
import
com.yonde.dex.dao.events.DxEventWrap
;
import
com.yonde.dex.dfs.vo.ObjFileLinkVO
;
import
com.yonde.dex.wfc.common.vo.DxWfProcessInfoVO
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.apache.commons.lang3.ObjectUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Component
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.lang.reflect.Method
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.List
;
/**
* @author xfchai
* @ClassName DocBeforeCreateEvent.java
* @Description 保存文档之前的操作事件
* @createTime 2021/11/15 14:29:00
*/
@Component
@Slf4j
@DxEvent
public
class
DocBeforeCreateEvent
{
//word模板路径
public
static
final
String
PATH
=
Constants
.
MTEMPLATE_ABSOLUTE_PATH
;
public
static
final
String
DOC_END_WITH
=
".doc"
;
public
static
final
String
DOCX_END_WITH
=
".docx"
;
@Autowired
private
ExtDocService
extDocService
;
@Autowired
private
ImportWordService
importWordService
;
@Autowired
TechnicalFileUtils
technicalFileUtils
;
@Autowired
private
ProcessDataUtils
processDataUtils
;
@Autowired
private
ExtDocUtil
extDocUtil
;
@DxEventListener
(
value
=
DxDocumentVO
.
class
,
eventType
=
BusinessEventType
.
BEFORE_CREATE
,
order
=
1
)
public
void
createDocListener
(
List
<
DxEventWrap
<
DxDocumentVO
>>
events
)
{
events
.
forEach
(
e
->
{
String
subTypeName
=
e
.
getTarget
().
getSubTypeName
();
//处理过时文件通知单
if
(
Constants
.
OUTDATED_NOTIFY
.
equals
(
subTypeName
))
{
processDataUtils
.
processOutdatedDocNotify
(
e
.
getTarget
());
}
else
if
(
ObjectUtils
.
isEmpty
(
e
.
getTarget
().
getMasterId
()))
{
//新建文档,校验编号是否存在
String
number
=
e
.
getTarget
().
getNumber
();
DxDocumentVO
dxDocumentVO
=
extDocUtil
.
searchDocByNumber
(
number
);
if
(!
ObjectUtils
.
isEmpty
(
dxDocumentVO
))
{
throw
new
DxBusinessException
(
"-1"
,
"文档编号已存在"
);
}
}
});
}
/**
* 审阅中编制任务后生成word文档
*
* @param documentVo
*/
public
DxDocumentVO
processCreateData
(
DxDocumentVO
documentVo
)
{
//查询展开ObjFileLink
DxDocumentVO
documentVO
=
extDocUtil
.
findDocObjFileLinks
(
documentVo
.
getId
());
//根据状态判断是否进行更新word(审阅中)
if
(
Constants
.
REVIEWING
.
equals
(
documentVO
.
getState
())
||
Constants
.
CAPITAL_RAISING
.
equals
(
documentVO
.
getState
()))
{
//技术文件(设计图册或者安装图册)
if
(
Constants
.
TECHNICAL_FILE
.
equals
(
documentVO
.
getDxDocumentExpand
().
getOneLevCategory
())
||
Constants
.
QAP_DOC
.
equals
(
documentVO
.
getDxDocumentExpand
().
getOneLevCategory
()))
{
this
.
generalTechnicalWord
(
documentVO
);
//删除生成后的临时文件
FileUtils
.
deleteDirectory
(
Constants
.
MERGER_FILE_ABSOLUTE_PATH
+
documentVO
.
getSubTypeName
()
+
File
.
separator
+
documentVO
.
getNumber
()
+
File
.
separator
);
}
else
{
//单据的操作
processDataUtils
.
processData
(
documentVO
);
}
}
return
documentVO
;
}
/**
* 修改文档事件
*
* @param events
*/
@DxEventListener
(
value
=
DxDocumentVO
.
class
,
eventType
=
BusinessEventType
.
BEFORE_UPDATE
,
order
=
1
)
public
void
updateDocListener
(
List
<
DxEventWrap
<
DxDocumentVO
>>
events
)
{
events
.
forEach
(
e
->
{
// DxDocumentVO target = e.getTarget();
// DxDocumentVO docObjFileLinks = extDocUtil.findDocObjFileLinks(target.getId());
// processUpdateData(docObjFileLinks);
// String subTypeName = e.getTarget().getSubTypeName();
// //处理过时文件通知单
// if (Constants.OUTDATED_NOTIFY.equals(subTypeName)) {
// processDataUtils.processOutdatedDocNotify(e.getTarget());
// } else if (ObjectUtils.isEmpty(e.getTarget().getMasterId())) {
// //新建文档,校验编号是否存在
// String number = e.getTarget().getNumber();
// DxDocumentVO dxDocumentVO = extDocUtil.searchDocByNumber(number);
// if (!ObjectUtils.isEmpty(dxDocumentVO)) {
// throw new DxBusinessException("-1", "文档编号已存在");
// processDataUtils.processOutdatedDocNotify(docObjFileLinks);
// }
// e.setTarget(docObjFileLinks);
});
}
/**
* 修改事件更新word
*
* @param documentVo
*/
public
void
processUpdateData
(
DxDocumentVO
documentVo
)
{
//根据状态判断是否进行更新word(不等于待审阅)
if
(!
Constants
.
PENDING_REVIEW
.
equals
(
documentVo
.
getState
()))
{
processDataUtils
.
processData
(
documentVo
);
}
}
/**
* 自动方法生成内部接口的word
*
* @param documentVo
* @param infoLinkVO 提资人信息
*/
public
void
generateAutoInterFaceWord
(
DxDocumentVO
documentVo
,
ExtInterfaceInfoLinkVO
infoLinkVO
,
DxWfProcessInfoVO
wfProcessInfoVO
)
{
try
{
String
file
=
documentVo
.
getSubTypeName
();
String
outWordFilePath
=
Constants
.
MERGER_FILE_ABSOLUTE_PATH
+
documentVo
.
getSubTypeName
()
+
"\\"
+
documentVo
.
getNumber
()
+
"\\"
+
Constants
.
MERGER_SOURCE
+
"\\"
;
//生成特定的文档目录,保存生成的word文件
FileUtil
.
mkdir
(
outWordFilePath
);
Class
<?>
clazz
=
Class
.
forName
(
"com.inet.pdm.factory.InternalInterfaceUtils"
);
Method
settingDataMethod
=
clazz
.
getMethod
(
"settingData"
,
DxDocumentVO
.
class
,
ExtInterfaceInfoLinkVO
.
class
,
DxWfProcessInfoVO
.
class
);
JSONObject
jsonObject
=
(
JSONObject
)
settingDataMethod
.
invoke
(
SpringUtil
.
getBean
(
InternalInterfaceUtils
.
class
),
documentVo
,
infoLinkVO
,
wfProcessInfoVO
);
String
generateWordFilePath
=
FileUtils
.
generateWordFile
(
outWordFilePath
);
//生成word文件方法
importWordService
.
getWordAllTable
(
jsonObject
,
PATH
+
file
+
".docx"
,
generateWordFilePath
);
log
.
info
(
"生成word文件内容结束===="
);
//按照目录获取生成的pdf和word
String
outFilePath
=
Constants
.
MERGER_FILE_ABSOLUTE_PATH
+
documentVo
.
getSubTypeName
()
+
"\\"
+
documentVo
.
getNumber
()
+
"\\"
+
Constants
.
MERGER_SOURCE
+
"\\"
;
//获取文件夹的所有文件--绝对路径
List
<
String
>
fileList
=
new
ArrayList
<>();
File
[]
files
=
FileUtil
.
ls
(
outFilePath
);
Arrays
.
stream
(
files
).
forEach
(
item
->
{
fileList
.
add
(
item
.
getAbsolutePath
());
});
if
(
CollectionUtils
.
isEmpty
(
fileList
))
{
log
.
error
(
"自动方法=====生成的word文件目录内容为空===="
);
}
log
.
info
(
"自动方法=====生成word文件完成!"
);
}
catch
(
Exception
e
)
{
log
.
error
(
"自动方法=====生成内部接口的word错误:"
+
e
.
getMessage
());
}
}
/**
* 生成技术文件word
*
* @param documentVo
*/
public
void
generalTechnicalWord
(
DxDocumentVO
documentVo
)
{
int
i
=
1
;
String
dirPath
=
Constants
.
MERGER_FILE_ABSOLUTE_PATH
+
documentVo
.
getSubTypeName
()
+
"\\"
+
documentVo
.
getNumber
()
+
"\\"
+
Constants
.
MERGER_TARGET
+
"\\"
;
String
outWordFilePath
=
Constants
.
MERGER_FILE_ABSOLUTE_PATH
+
documentVo
.
getSubTypeName
()
+
"\\"
+
documentVo
.
getNumber
()
+
"\\"
;
FileUtil
.
mkdir
(
dirPath
);
//生成特定的文档目录,保存生成的word文件
String
outPath
=
FileUtil
.
mkdir
(
outWordFilePath
).
getPath
();
if
(
Constants
.
TECHNICAL_FILE
.
equals
(
documentVo
.
getDxDocumentExpand
().
getOneLevCategory
()))
{
JSONObject
secretJson
=
technicalFileUtils
.
settingSecretData
(
documentVo
);
//生成密级封皮word文件方法
importWordService
.
getWordAllTable
(
secretJson
,
Constants
.
TEMPLATE_PATH
+
"TechnicalFile/"
+
"TechnicalFileSecret.docx"
,
outPath
+
"/"
+
i
+
"TechnicalFileSecret.docx"
);
i
++;
//秘密,机密生成两张密级页
if
(
"Secret"
.
equals
(
documentVo
.
getSecretCode
())
||
"Confidential"
.
equals
(
documentVo
.
getSecretCode
()))
{
//生成密级封皮word文件方法
importWordService
.
getWordAllTable
(
secretJson
,
Constants
.
TEMPLATE_PATH
+
"TechnicalFile/"
+
"TechnicalFileSecret.docx"
,
outPath
+
"/"
+
i
+
"TechnicalFileSecret.docx"
);
i
++;
}
JSONObject
interfaceHQJson
=
technicalFileUtils
.
settingInterfaceHQData
(
documentVo
);
//生成接口会签封皮word文件方法
importWordService
.
getWordAllTable
(
interfaceHQJson
,
Constants
.
TEMPLATE_PATH
+
"TechnicalFile/"
+
"TechnicalFileInterfaceHQ.docx"
,
outPath
+
"/"
+
i
+
"TechnicalFileInterfaceHQ.docx"
);
i
++;
JSONObject
auditJson
=
technicalFileUtils
.
settingAuditData
(
documentVo
);
//生成专项审查封皮word文件方法
importWordService
.
getWordAllTable
(
auditJson
,
Constants
.
TEMPLATE_PATH
+
"TechnicalFile/"
+
"TechnicalFileAudit.docx"
,
outPath
+
"/"
+
i
+
"TechnicalFileAudit.docx"
);
i
++;
JSONObject
historyJson
=
technicalFileUtils
.
settingHistoryData
(
documentVo
);
//生成历史版本封皮word文件方法
importWordService
.
getWordAllTable
(
historyJson
,
Constants
.
TEMPLATE_PATH
+
"TechnicalFile/"
+
"TechnicalFileHistory.docx"
,
outPath
+
"/"
+
i
+
"TechnicalFileHistory.docx"
);
i
++;
if
(
Constants
.
DESIGN_ATLAS
.
equals
(
documentVo
.
getSubTypeName
())
||
Constants
.
INSTALL_ATLAS
.
equals
(
documentVo
.
getSubTypeName
()))
{
JSONObject
drawingsJson
=
technicalFileUtils
.
settingAtlasCategoryData
(
documentVo
);
//生成图册图纸封皮word文件方法
importWordService
.
getWordAllTable
(
drawingsJson
,
Constants
.
TEMPLATE_PATH
+
"TechnicalFile/"
+
"TechnicalFileAtlasCategory.docx"
,
outPath
+
"/"
+
i
+
"TechnicalFileAtlasCategory.docx"
);
i
++;
}
}
else
if
(
Constants
.
QAP_DOC
.
equals
(
documentVo
.
getDxDocumentExpand
().
getOneLevCategory
()))
{
JSONObject
qapJson
=
technicalFileUtils
.
settingHistoryData
(
documentVo
);
//生成历史版本封皮word文件方法
importWordService
.
getWordAllTable
(
qapJson
,
Constants
.
TEMPLATE_PATH
+
"QAPFile/"
+
"QAPCover.docx"
,
outPath
+
"/"
+
i
+
"QAPCover.docx"
);
i
++;
}
//(图册除外)合并用户上传的主内容word
if
(!(
Constants
.
DESIGN_ATLAS
.
equals
(
documentVo
.
getSubTypeName
())
||
Constants
.
INSTALL_ATLAS
.
equals
(
documentVo
.
getSubTypeName
())))
{
InputStream
inputStream
=
null
;
List
<
ObjFileLinkVO
>
objFileLinks
=
documentVo
.
getObjFileLinks
();
//判断是否为word,不是word不合并
if
(!
CollectionUtils
.
isEmpty
(
objFileLinks
))
{
//todo 获取主内容数据流
// PapersVO fileVO = extDocUtil.obtainPrimaryFile(objFileLinks);
// if (!ObjectUtils.isEmpty(fileVO) && (fileVO.getOriginalFileName().endsWith(DOC_END_WITH) || fileVO.getOriginalFileName().endsWith(DOCX_END_WITH))) {
// inputStream = extDocUtil.obtainPrimaryFileInputStream(fileVO);
// //保存临时文件
// String filePath = FileUtils.saveToLocal(inputStream, outWordFilePath + fileVO.getOriginalFileName());
// log.info("临时文件目录为:", filePath);
// //先将word转为pdf,再合并
// Word2PdfJacobUtil.word2PDF(filePath, outPath + "/" + i + "MasterFile.pdf");
// }
// });
// }
//
// /**
// * 审阅中编制任务后生成word文档
// *
// * @param documentVo
// */
// public DxDocumentVO processCreateData(DxDocumentVO documentVo) {
// //查询展开ObjFileLink
// DxDocumentVO documentVO = extDocUtil.findDocObjFileLinks(documentVo.getId());
// //根据状态判断是否进行更新word(审阅中)
// if (Constants.REVIEWING.equals(documentVO.getState()) || Constants.CAPITAL_RAISING.equals(documentVO.getState())) {
// //技术文件(设计图册或者安装图册)
// if (Constants.TECHNICAL_FILE.equals(documentVO.getDxDocumentExpand().getOneLevCategory()) || Constants.QAP_DOC.equals(documentVO.getDxDocumentExpand().getOneLevCategory())) {
// this.generalTechnicalWord(documentVO);
// //删除生成后的临时文件
// FileUtils.deleteDirectory(Constants.MERGER_FILE_ABSOLUTE_PATH + documentVO.getSubTypeName() + File.separator + documentVO.getNumber() + File.separator);
// } else {
// //单据的操作
// processDataUtils.processData(documentVO);
// }
// }
// return documentVO;
// }
//
// /**
// * 修改文档事件
// *
// * @param events
// */
// @DxEventListener(value = DxDocumentVO.class, eventType = BusinessEventType.BEFORE_UPDATE, order = 1)
// public void updateDocListener(List<DxEventWrap<DxDocumentVO>> events) {
// events.forEach(e -> {
//// DxDocumentVO target = e.getTarget();
//// DxDocumentVO docObjFileLinks = extDocUtil.findDocObjFileLinks(target.getId());
//// processUpdateData(docObjFileLinks);
//// String subTypeName = e.getTarget().getSubTypeName();
//// //处理过时文件通知单
//// if (Constants.OUTDATED_NOTIFY.equals(subTypeName)) {
//// processDataUtils.processOutdatedDocNotify(docObjFileLinks);
//// }
//// e.setTarget(docObjFileLinks);
// });
// }
//
// /**
// * 修改事件更新word
// *
// * @param documentVo
// */
// public void processUpdateData(DxDocumentVO documentVo) {
// //根据状态判断是否进行更新word(不等于待审阅)
// if (!Constants.PENDING_REVIEW.equals(documentVo.getState())) {
// processDataUtils.processData(documentVo);
// }
// }
//
// /**
// * 自动方法生成内部接口的word
// *
// * @param documentVo
// * @param infoLinkVO 提资人信息
// */
// public void generateAutoInterFaceWord(DxDocumentVO documentVo, ExtInterfaceInfoLinkVO infoLinkVO, DxWfProcessInfoVO wfProcessInfoVO) {
// try {
// String file = documentVo.getSubTypeName();
// String outWordFilePath = Constants.MERGER_FILE_ABSOLUTE_PATH + documentVo.getSubTypeName() + "\\" + documentVo.getNumber() + "\\" + Constants.MERGER_SOURCE + "\\";
// //生成特定的文档目录,保存生成的word文件
// FileUtil.mkdir(outWordFilePath);
// Class<?> clazz = Class.forName("com.inet.pdm.factory.InternalInterfaceUtils");
// Method settingDataMethod = clazz.getMethod("settingData", DxDocumentVO.class, ExtInterfaceInfoLinkVO.class, DxWfProcessInfoVO.class);
// JSONObject jsonObject = (JSONObject) settingDataMethod.invoke(SpringUtil.getBean(InternalInterfaceUtils.class), documentVo, infoLinkVO, wfProcessInfoVO);
// String generateWordFilePath = FileUtils.generateWordFile(outWordFilePath);
// //生成word文件方法
// importWordService.getWordAllTable(jsonObject, PATH + file + ".docx", generateWordFilePath);
// log.info("生成word文件内容结束====");
// //按照目录获取生成的pdf和word
// String outFilePath = Constants.MERGER_FILE_ABSOLUTE_PATH + documentVo.getSubTypeName() + "\\" + documentVo.getNumber() + "\\" + Constants.MERGER_SOURCE + "\\";
// //获取文件夹的所有文件--绝对路径
// List<String> fileList = new ArrayList<>();
// File[] files = FileUtil.ls(outFilePath);
// Arrays.stream(files).forEach(item -> {
// fileList.add(item.getAbsolutePath());
// });
// if (CollectionUtils.isEmpty(fileList)) {
// log.error("自动方法=====生成的word文件目录内容为空====");
// }
// log.info("自动方法=====生成word文件完成!");
// } catch (Exception e) {
// log.error("自动方法=====生成内部接口的word错误:" + e.getMessage());
// }
// }
//
// /**
// * 生成技术文件word
// *
// * @param documentVo
// */
// public void generalTechnicalWord(DxDocumentVO documentVo) {
// int i = 1;
// String dirPath = Constants.MERGER_FILE_ABSOLUTE_PATH + documentVo.getSubTypeName() + "\\" + documentVo.getNumber() + "\\" + Constants.MERGER_TARGET + "\\";
// String outWordFilePath = Constants.MERGER_FILE_ABSOLUTE_PATH + documentVo.getSubTypeName() + "\\" + documentVo.getNumber() + "\\";
// FileUtil.mkdir(dirPath);
// //生成特定的文档目录,保存生成的word文件
// String outPath = FileUtil.mkdir(outWordFilePath).getPath();
//
// if (Constants.TECHNICAL_FILE.equals(documentVo.getDxDocumentExpand().getOneLevCategory())) {
// JSONObject secretJson = technicalFileUtils.settingSecretData(documentVo);
// //生成密级封皮word文件方法
// importWordService.getWordAllTable(secretJson, Constants.TEMPLATE_PATH + "TechnicalFile/" + "TechnicalFileSecret.docx", outPath + "/" + i + "TechnicalFileSecret.docx");
// i++;
// //秘密,机密生成两张密级页
// if ("Secret".equals(documentVo.getSecretCode()) || "Confidential".equals(documentVo.getSecretCode())) {
// //生成密级封皮word文件方法
// importWordService.getWordAllTable(secretJson, Constants.TEMPLATE_PATH + "TechnicalFile/" + "TechnicalFileSecret.docx", outPath + "/" + i + "TechnicalFileSecret.docx");
// i++;
// }
//
// JSONObject interfaceHQJson = technicalFileUtils.settingInterfaceHQData(documentVo);
// //生成接口会签封皮word文件方法
// importWordService.getWordAllTable(interfaceHQJson, Constants.TEMPLATE_PATH + "TechnicalFile/" + "TechnicalFileInterfaceHQ.docx", outPath + "/" + i + "TechnicalFileInterfaceHQ.docx");
// i++;
//
//
// JSONObject auditJson = technicalFileUtils.settingAuditData(documentVo);
// //生成专项审查封皮word文件方法
// importWordService.getWordAllTable(auditJson, Constants.TEMPLATE_PATH + "TechnicalFile/" + "TechnicalFileAudit.docx", outPath + "/" + i + "TechnicalFileAudit.docx");
// i++;
//
// JSONObject historyJson = technicalFileUtils.settingHistoryData(documentVo);
// //生成历史版本封皮word文件方法
// importWordService.getWordAllTable(historyJson, Constants.TEMPLATE_PATH + "TechnicalFile/" + "TechnicalFileHistory.docx", outPath + "/" + i + "TechnicalFileHistory.docx");
// i++;
//
// if (Constants.DESIGN_ATLAS.equals(documentVo.getSubTypeName()) || Constants.INSTALL_ATLAS.equals(documentVo.getSubTypeName())) {
// JSONObject drawingsJson = technicalFileUtils.settingAtlasCategoryData(documentVo);
// //生成图册图纸封皮word文件方法
// importWordService.getWordAllTable(drawingsJson, Constants.TEMPLATE_PATH + "TechnicalFile/" + "TechnicalFileAtlasCategory.docx", outPath + "/" + i + "TechnicalFileAtlasCategory.docx");
// i++;
// }
// } else if (Constants.QAP_DOC.equals(documentVo.getDxDocumentExpand().getOneLevCategory())) {
// JSONObject qapJson = technicalFileUtils.settingHistoryData(documentVo);
// //生成历史版本封皮word文件方法
// importWordService.getWordAllTable(qapJson, Constants.TEMPLATE_PATH + "QAPFile/" + "QAPCover.docx", outPath + "/" + i + "QAPCover.docx");
// i++;
// }
//
//
// //(图册除外)合并用户上传的主内容word
// if (!(Constants.DESIGN_ATLAS.equals(documentVo.getSubTypeName()) || Constants.INSTALL_ATLAS.equals(documentVo.getSubTypeName()))) {
// InputStream inputStream = null;
// List<ObjFileLinkVO> objFileLinks = documentVo.getObjFileLinks();
// //判断是否为word,不是word不合并
// if (!CollectionUtils.isEmpty(objFileLinks)) {
// //todo 获取主内容数据流
//// PapersVO fileVO = extDocUtil.obtainPrimaryFile(objFileLinks);
//// if (!ObjectUtils.isEmpty(fileVO) && (fileVO.getOriginalFileName().endsWith(DOC_END_WITH) || fileVO.getOriginalFileName().endsWith(DOCX_END_WITH))) {
//// inputStream = extDocUtil.obtainPrimaryFileInputStream(fileVO);
//// //保存临时文件
//// String filePath = FileUtils.saveToLocal(inputStream, outWordFilePath + fileVO.getOriginalFileName());
//// log.info("临时文件目录为:", filePath);
//// //先将word转为pdf,再合并
//// Word2PdfJacobUtil.word2PDF(filePath, outPath + "/" + i + "MasterFile.pdf");
//// }
// }
// }
// //合并生成好的文档
// FileUtils.mergePdfFile(outPath, dirPath + Constants.MERGER_PDF_FILE_NAME);
// try {
// //将pdf上传到附件中
// extDocService.extractedAttachFile(documentVo, new FileInputStream(dirPath + Constants.MERGER_PDF_FILE_NAME), "附件一", Constants.ATTACH_FILE);
// } catch (IOException e) {
// log.error("文件输入错误!");
// } catch (Exception e) {
// log.error("上传附件错误!");
// }
// }
//
// public void generalQAPWord(DxDocumentVO documentVo) {
//
// }
//}
}
}
//合并生成好的文档
FileUtils
.
mergePdfFile
(
outPath
,
dirPath
+
Constants
.
MERGER_PDF_FILE_NAME
);
try
{
//将pdf上传到附件中
extDocService
.
extractedAttachFile
(
documentVo
,
new
FileInputStream
(
dirPath
+
Constants
.
MERGER_PDF_FILE_NAME
),
"附件一"
,
Constants
.
ATTACH_FILE
);
}
catch
(
IOException
e
)
{
log
.
error
(
"文件输入错误!"
);
}
catch
(
Exception
e
)
{
log
.
error
(
"上传附件错误!"
);
}
}
public
void
generalQAPWord
(
DxDocumentVO
documentVo
)
{
}
}
dcs-doc-expand-core/src/main/java/com/yonde/dcs/core/events/ProcessDataUtils.java
View file @
7988a858
//package com.yonde.dcs.core.events;
//
//import cn.hutool.core.io.FileUtil;
//import cn.hutool.extra.spring.SpringUtil;
//import com.alibaba.fastjson.JSONObject;
//
//import com.yonde.dcs.common.vo.ExtInterfaceInfoLinkVO;
//import com.yonde.dcs.core.constants.Constants;
//import com.yonde.dcs.core.factory.InternalInterfaceUtils;
//import com.yonde.dcs.core.factory.OutdatedDocNotifyUtils;
//import com.yonde.dcs.core.service.ExtDocService;
//import com.yonde.dcs.core.util.ExtDocUtil;
//import com.yonde.dcs.core.util.FileUtils;
//import com.yonde.dcs.core.util.WorkFlowUtil;
//import com.yonde.dcs.core.word.ImportWordService;
//import com.yonde.dcs.document.common.entity.vo.DxDocumentVO;
//import com.yonde.dex.wfc.common.vo.DxWfProcessInfoVO;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Component;
//import org.springframework.util.CollectionUtils;
//
//import java.io.File;
//import java.io.FileInputStream;
//import java.lang.reflect.Method;
//import java.util.ArrayList;
//import java.util.Arrays;
//import java.util.List;
//
///**
// * @author xfchai
// * @ClassName ProcessDataUtils.java
// * @Description 数据处理工具类
// * @createTime 2022/02/23 16:11:00
// */
//@Component
//@Slf4j
//public class ProcessDataUtils {
// //word模板路径
// public static final String PATH = Constants.MTEMPLATE_ABSOLUTE_PATH;
package
com
.
yonde
.
dcs
.
core
.
events
;
import
cn.hutool.core.io.FileUtil
;
import
cn.hutool.extra.spring.SpringUtil
;
import
com.alibaba.fastjson.JSONObject
;
import
com.yonde.dcs.common.vo.ExtInterfaceInfoLinkVO
;
import
com.yonde.dcs.core.constants.Constants
;
import
com.yonde.dcs.core.factory.InternalInterfaceUtils
;
import
com.yonde.dcs.core.factory.OutdatedDocNotifyUtils
;
import
com.yonde.dcs.core.service.ExtDocService
;
import
com.yonde.dcs.core.util.ExtDocUtil
;
import
com.yonde.dcs.core.util.FileUtils
;
import
com.yonde.dcs.core.util.WorkFlowUtil
;
import
com.yonde.dcs.core.word.ImportWordService
;
import
com.yonde.dcs.document.common.entity.vo.DxDocumentVO
;
import
com.yonde.dex.wfc.common.vo.DxWfProcessInfoVO
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Component
;
import
org.springframework.util.CollectionUtils
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.lang.reflect.Method
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.List
;
/**
* @author xfchai
* @ClassName ProcessDataUtils.java
* @Description 数据处理工具类
* @createTime 2022/02/23 16:11:00
*/
@Component
@Slf4j
public
class
ProcessDataUtils
{
//word模板路径
public
static
final
String
PATH
=
Constants
.
MTEMPLATE_ABSOLUTE_PATH
;
@Autowired
private
ExtDocService
extDocService
;
@Autowired
private
ImportWordService
importWordService
;
@Autowired
private
ExtDocUtil
extDocUtil
;
@Autowired
private
WorkFlowUtil
workFlowUtil
;
// @Autowired
// private ExtDocService extDocService;
// @Autowired
// private ImportWordService importWordService;
// @Autowired
// private ExtDocUtil extDocUtil;
// @Autowired
// private WorkFlowUtil workFlowUtil;
//// @Autowired
//// private DexWorkFlowService dexWorkFlowService;
//
// /**
// * 单独处理过时文件通知单数据
// */
// public void processOutdatedDocNotify(DxDocumentVO documentVo) {
// extDocService.getDocWord(documentVo, OutdatedDocNotifyUtils.class, new DxWfProcessInfoVO(), "");
// }
//
// /**
// * 处理单据word数据
// *
// * @param documentVo
// */
// public void processData(DxDocumentVO documentVo) {
// String subTypeName = documentVo.getSubTypeName();
// //todo
//// WfProcessInstVO DxWfProcessInstVO = workFlowUtil.getWfProcessInst(documentVo);
//// DxWfProcessInfoVO wfProcessInfoVO = dexWorkFlowService.getProcessInstDetailById(DxWfProcessInstVO.getId());
//// switch (subTypeName) {
//// case Constants.INTERNAL_INTERFACE:
//// this.generateInterFaceWord(documentVo, new InterfaceInfoLinkVO(), wfProcessInfoVO);
//// break;
//// case Constants.CONTACTLIST:
//// extDocService.getDocWord(documentVo, ContactListUtils.class, wfProcessInfoVO, "一");
//// break;
//// case Constants.WORK_CONTACTLIST:
//// extDocService.getDocWord(documentVo, WorkContactListUtils.class, wfProcessInfoVO, "");
//// break;
//// case Constants.DESIGN_CHANGE:
//// extDocService.getDocWord(documentVo, DesignChangeUtils.class, wfProcessInfoVO, "");
//// break;
//// case Constants.DESIGN_APPLICATION:
//// extDocService.getDocWord(documentVo, DesignDocApplicatUtils.class, wfProcessInfoVO, "");
//// break;
//// case Constants.DESIGN_ENTER:
//// extDocService.getDocWord(documentVo, DesignEnterUtils.class, wfProcessInfoVO, "");
//// break;
//// case Constants.NCR:
//// extDocService.getDocWord(documentVo, NCRUtils.class, wfProcessInfoVO, "");
//// break;
//// case Constants.DEN:
//// //根据模板生成两张不同澄清单
//// extDocService.getDocWord(documentVo, DENUtils.class, wfProcessInfoVO, "");
//// break;
//// }
// }
//
// /**
// * 新建内部接口文档-生成内部接口的word
// *
// * @param documentVo
// * @param infoLinkVO 提资人信息
// */
// public void generateInterFaceWord(DxDocumentVO documentVo, ExtInterfaceInfoLinkVO infoLinkVO, DxWfProcessInfoVO wfProcessInfoVO) {
// try {
// String file = documentVo.getSubTypeName();
// String outWordFilePath = Constants.MERGER_FILE_ABSOLUTE_PATH + documentVo.getSubTypeName() + "\\" + documentVo.getNumber() + "\\";
// //生成特定的文档目录,保存生成的word文件
// FileUtil.mkdir(outWordFilePath);
// Class<?> clazz = Class.forName("com.inet.pdm.factory.InternalInterfaceUtils");
// Method settingDataMethod = clazz.getMethod("settingData", DxDocumentVO.class, ExtInterfaceInfoLinkVO.class, DxWfProcessInfoVO.class);
// JSONObject jsonObject = (JSONObject) settingDataMethod.invoke(SpringUtil.getBean(InternalInterfaceUtils.class), documentVo, infoLinkVO, wfProcessInfoVO);
// //生成word文件方法
// importWordService.getWordAllTable(jsonObject, PATH + file + ".docx", outWordFilePath + "outFile.docx");
// log.info("生成word文件内容结束====");
// //获取文件夹的所有文件--绝对路径
// List<String> fileList = new ArrayList<>();
// File[] files = FileUtil.ls(outWordFilePath);
// Arrays.stream(files).forEach(item -> {
// fileList.add(item.getAbsolutePath());
// });
// if (CollectionUtils.isEmpty(fileList)) {
// log.error("生成的word文件目录内容为空====");
// } else {
//// String filePath = fileList.stream().filter(item -> item.endsWith(".docx")).findFirst().get();
// String pdfFilePath = fileList.stream().filter(item -> item.endsWith(".pdf")).findFirst().get();
// //将pdf上传到附件中
// extDocService.extractedAttachFile(documentVo, new FileInputStream(pdfFilePath), "", Constants.ATTACH_FILE);
// log.info("获取生成的word文件内容结束====");
// }
// //删除生成后的临时文件
// FileUtils.deleteDirectory(Constants.MERGER_FILE_ABSOLUTE_PATH + documentVo.getSubTypeName() + "\\" + documentVo.getNumber());
// } catch (Exception e) {
// log.error("新建内部接口文档-生成内部接口的word错误:{}" + e.getMessage());
// }
// private DexWorkFlowService dexWorkFlowService;
/**
* 单独处理过时文件通知单数据
*/
public
void
processOutdatedDocNotify
(
DxDocumentVO
documentVo
)
{
extDocService
.
getDocWord
(
documentVo
,
OutdatedDocNotifyUtils
.
class
,
new
DxWfProcessInfoVO
(),
""
);
}
/**
* 处理单据word数据
*
* @param documentVo
*/
public
void
processData
(
DxDocumentVO
documentVo
)
{
String
subTypeName
=
documentVo
.
getSubTypeName
();
//todo
// WfProcessInstVO DxWfProcessInstVO = workFlowUtil.getWfProcessInst(documentVo);
// DxWfProcessInfoVO wfProcessInfoVO = dexWorkFlowService.getProcessInstDetailById(DxWfProcessInstVO.getId());
// switch (subTypeName) {
// case Constants.INTERNAL_INTERFACE:
// this.generateInterFaceWord(documentVo, new InterfaceInfoLinkVO(), wfProcessInfoVO);
// break;
// case Constants.CONTACTLIST:
// extDocService.getDocWord(documentVo, ContactListUtils.class, wfProcessInfoVO, "一");
// break;
// case Constants.WORK_CONTACTLIST:
// extDocService.getDocWord(documentVo, WorkContactListUtils.class, wfProcessInfoVO, "");
// break;
// case Constants.DESIGN_CHANGE:
// extDocService.getDocWord(documentVo, DesignChangeUtils.class, wfProcessInfoVO, "");
// break;
// case Constants.DESIGN_APPLICATION:
// extDocService.getDocWord(documentVo, DesignDocApplicatUtils.class, wfProcessInfoVO, "");
// break;
// case Constants.DESIGN_ENTER:
// extDocService.getDocWord(documentVo, DesignEnterUtils.class, wfProcessInfoVO, "");
// break;
// case Constants.NCR:
// extDocService.getDocWord(documentVo, NCRUtils.class, wfProcessInfoVO, "");
// break;
// case Constants.DEN:
// //根据模板生成两张不同澄清单
// extDocService.getDocWord(documentVo, DENUtils.class, wfProcessInfoVO, "");
// break;
// }
//}
}
/**
* 新建内部接口文档-生成内部接口的word
*
* @param documentVo
* @param infoLinkVO 提资人信息
*/
public
void
generateInterFaceWord
(
DxDocumentVO
documentVo
,
ExtInterfaceInfoLinkVO
infoLinkVO
,
DxWfProcessInfoVO
wfProcessInfoVO
)
{
try
{
String
file
=
documentVo
.
getSubTypeName
();
String
outWordFilePath
=
Constants
.
MERGER_FILE_ABSOLUTE_PATH
+
documentVo
.
getSubTypeName
()
+
"\\"
+
documentVo
.
getNumber
()
+
"\\"
;
//生成特定的文档目录,保存生成的word文件
FileUtil
.
mkdir
(
outWordFilePath
);
Class
<?>
clazz
=
Class
.
forName
(
"com.inet.pdm.factory.InternalInterfaceUtils"
);
Method
settingDataMethod
=
clazz
.
getMethod
(
"settingData"
,
DxDocumentVO
.
class
,
ExtInterfaceInfoLinkVO
.
class
,
DxWfProcessInfoVO
.
class
);
JSONObject
jsonObject
=
(
JSONObject
)
settingDataMethod
.
invoke
(
SpringUtil
.
getBean
(
InternalInterfaceUtils
.
class
),
documentVo
,
infoLinkVO
,
wfProcessInfoVO
);
//生成word文件方法
importWordService
.
getWordAllTable
(
jsonObject
,
PATH
+
file
+
".docx"
,
outWordFilePath
+
"outFile.docx"
);
log
.
info
(
"生成word文件内容结束===="
);
//获取文件夹的所有文件--绝对路径
List
<
String
>
fileList
=
new
ArrayList
<>();
File
[]
files
=
FileUtil
.
ls
(
outWordFilePath
);
Arrays
.
stream
(
files
).
forEach
(
item
->
{
fileList
.
add
(
item
.
getAbsolutePath
());
});
if
(
CollectionUtils
.
isEmpty
(
fileList
))
{
log
.
error
(
"生成的word文件目录内容为空===="
);
}
else
{
// String filePath = fileList.stream().filter(item -> item.endsWith(".docx")).findFirst().get();
String
pdfFilePath
=
fileList
.
stream
().
filter
(
item
->
item
.
endsWith
(
".pdf"
)).
findFirst
().
get
();
//将pdf上传到附件中
extDocService
.
extractedAttachFile
(
documentVo
,
new
FileInputStream
(
pdfFilePath
),
""
,
Constants
.
ATTACH_FILE
);
log
.
info
(
"获取生成的word文件内容结束===="
);
}
//删除生成后的临时文件
FileUtils
.
deleteDirectory
(
Constants
.
MERGER_FILE_ABSOLUTE_PATH
+
documentVo
.
getSubTypeName
()
+
"\\"
+
documentVo
.
getNumber
());
}
catch
(
Exception
e
)
{
log
.
error
(
"新建内部接口文档-生成内部接口的word错误:{}"
+
e
.
getMessage
());
}
}
}
dcs-doc-expand-core/src/main/java/com/yonde/dcs/core/service/impl/expand/ExtDxDocumentServiceImpl.java
View file @
7988a858
...
...
@@ -2,6 +2,8 @@ package com.yonde.dcs.core.service.impl.expand;
import
org.springframework.stereotype.Service
;
import
io.swagger.annotations.ApiOperation
;
import
java.util.Collection
;
import
java.util.List
;
import
com.yonde.dcs.document.common.entity.vo.DxDocumentVO
;
import
org.springframework.beans.factory.annotation.Qualifier
;
...
...
@@ -30,6 +32,16 @@ public class ExtDxDocumentServiceImpl<V extends DxDocumentVO> extends DocumentSe
@Autowired
DocumentRepository
<
DxDocument
>
documentRepository
;
@Override
public
void
beforeSave
(
Collection
<
V
>
target
)
{
//循环处理每一个文档
for
(
V
v
:
target
)
{
}
super
.
beforeSave
(
target
);
}
dcs-doc-expand-core/src/main/java/com/yonde/dcs/core/util/WordMarkUtil.java
0 → 100644
View file @
7988a858
package
com
.
yonde
.
dcs
.
document
.
core
.
util
;
import
com.aspose.words.*
;
import
com.aspose.words.ParagraphAlignment
;
import
com.google.common.collect.Lists
;
import
com.microsoft.schemas.office.office.CTLock
;
import
com.microsoft.schemas.vml.*
;
import
lombok.SneakyThrows
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.apache.commons.io.IOUtils
;
import
org.apache.logging.log4j.util.Strings
;
import
org.apache.poi.ooxml.POIXMLDocument
;
import
org.apache.poi.openxml4j.exceptions.InvalidFormatException
;
import
org.apache.poi.util.Units
;
import
org.apache.poi.wp.usermodel.HeaderFooterType
;
import
org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy
;
import
org.apache.poi.xwpf.usermodel.*
;
import
org.apache.poi.xwpf.usermodel.Document
;
import
org.openxmlformats.schemas.wordprocessingml.x2006.main.*
;
import
org.w3c.dom.Node
;
import
javax.imageio.ImageIO
;
import
java.awt.image.BufferedImage
;
import
java.io.*
;
import
java.util.*
;
import
java.util.List
;
import
java.util.stream.Stream
;
/**
* @author 954L
* @create 2021/12/9 10:23
*/
public
class
WordMarkUtil
{
/**
* 水印字体字体
*/
private
static
final
String
fontName
=
"PingFang SC"
;
/**
* 一个字平均长度,单位pt,用于:计算文本占用的长度(文本总个数*单字长度)
*/
private
static
final
int
widthPerWord
=
10
;
/**
* 替换word内容 替换文字(不替换图片) 只能替换docx的文档
*
* @param src 原word文件地址
* @param dest 转换后word文件地址
* @param params 替换参数map
* @throws Exception
*/
@SneakyThrows
public
static
void
replace
(
String
src
,
String
dest
,
Map
<
String
,
String
>
params
)
{
XWPFDocument
document
=
new
XWPFDocument
(
POIXMLDocument
.
openPackage
(
src
));
// 页眉内容替换
replaceHeader
(
document
,
params
);
// replaceHeader1(document, params);
// 页脚替换
replaceFooter
(
document
,
params
);
// 基础内容替换
replaceParagraph
(
document
,
params
);
// 表格内容替换
replaceTable
(
Lists
.
newArrayList
(
document
.
getTablesIterator
()),
params
);
try
(
FileOutputStream
outStream
=
new
FileOutputStream
(
dest
))
{
document
.
write
(
outStream
);
}
}
/**
* 校验替换key值是否存在
*
* @param is
* @param signkeys
*/
@SneakyThrows
public
static
void
checkSignKey
(
InputStream
is
,
Map
<
String
,
String
>
signkeys
)
{
com
.
aspose
.
words
.
Document
document
=
new
com
.
aspose
.
words
.
Document
(
is
);
BookmarkCollection
bookmarks
=
document
.
getRange
().
getBookmarks
();
checkTableKeys
(
bookmarks
,
signkeys
);
}
/**
* 校验文档表格替换Key是否存在
*
* @param bookmarks
* @param params
*/
private
static
void
checkTableKeys
(
BookmarkCollection
bookmarks
,
Map
<
String
,
String
>
params
)
{
// 检查集合中的元素是否都在 Map 的键集合中
for
(
Bookmark
bookmark
:
bookmarks
)
{
String
name
=
bookmark
.
getName
();
if
(
params
.
containsKey
(
name
))
{
params
.
remove
(
name
);
}
}
}
/**
* 处理段落
*
* @param paragraphs
* @param params
*/
private
static
void
dealParagraphs
(
List
<
XWPFParagraph
>
paragraphs
,
Map
<
String
,
String
>
params
)
{
if
(
CollectionUtils
.
isNotEmpty
(
paragraphs
))
{
for
(
XWPFParagraph
paragraph
:
paragraphs
)
{
for
(
String
key
:
params
.
keySet
())
{
replaceInParagraph
(
paragraph
,
key
,
params
.
get
(
key
));
//TODO:测试替换
/*if (paragraph.getText().contains(key)) {
replaceInParagraph(paragraph, key, params.get(key));
}*/
}
}
}
}
/**
* 替换脚
*
* @param document
* @param params
*/
private
static
void
replaceFooter
(
XWPFDocument
document
,
Map
<
String
,
String
>
params
)
{
List
<
XWPFFooter
>
footerList
=
document
.
getFooterList
();
for
(
XWPFFooter
xwpfFooter
:
footerList
)
{
List
<
XWPFParagraph
>
paragraphs
=
xwpfFooter
.
getParagraphs
();
dealParagraphs
(
paragraphs
,
params
);
//TODO 处理页脚中的表格内容
List
<
XWPFTable
>
tables
=
xwpfFooter
.
getTables
();
replaceTable
(
tables
,
params
);
}
}
private
static
void
replaceHeader1
(
XWPFDocument
document
,
Map
<
String
,
String
>
params
)
{
List
<
XWPFHeader
>
headerList
=
document
.
getHeaderList
();
for
(
XWPFHeader
xwpfHeader
:
headerList
)
{
List
<
XWPFParagraph
>
paragraphs
=
xwpfHeader
.
getParagraphs
();
for
(
XWPFParagraph
paragraph
:
paragraphs
)
{
List
<
XWPFRun
>
runs
=
paragraph
.
getRuns
();
for
(
int
i
=
0
;
i
<
runs
.
size
();
i
++)
{
for
(
String
s
:
params
.
keySet
())
{
if
(
runs
.
get
(
i
).
getText
(
runs
.
get
(
i
).
getTextPosition
())
!=
null
&&
runs
.
get
(
i
).
getText
(
runs
.
get
(
i
).
getTextPosition
()).
contains
(
s
))
{
String
replace
=
runs
.
get
(
i
).
getText
(
runs
.
get
(
i
).
getTextPosition
()).
replace
(
s
,
params
.
get
(
s
));
runs
.
get
(
i
).
setText
(
replace
,
0
);
}
}
}
}
}
}
/**
* 替换表头
*
* @param document
* @param params
*/
private
static
void
replaceHeader
(
XWPFDocument
document
,
Map
<
String
,
String
>
params
)
{
List
<
XWPFHeader
>
headerList
=
document
.
getHeaderList
();
for
(
XWPFHeader
xwpfHeader
:
headerList
)
{
List
<
XWPFParagraph
>
paragraphs
=
xwpfHeader
.
getParagraphs
();
dealParagraphs
(
paragraphs
,
params
);
//TODO 处理页脚中的表格内容
List
<
XWPFTable
>
tables
=
xwpfHeader
.
getTables
();
replaceTable
(
tables
,
params
);
}
}
/**
* 替换普通文本
*
* @param document
* @param params
*/
private
static
void
replaceParagraph
(
XWPFDocument
document
,
Map
<
String
,
String
>
params
)
{
List
<
XWPFParagraph
>
xwpfParagraphList
=
document
.
getParagraphs
();
for
(
int
i
=
0
,
size
=
xwpfParagraphList
.
size
();
i
<
size
;
i
++)
{
XWPFParagraph
xwpfParagraph
=
xwpfParagraphList
.
get
(
i
);
for
(
String
key
:
params
.
keySet
())
{
//TODO:测试替换
//if (xwpfParagraph.getText().contains(key))
replaceInParagraph
(
xwpfParagraph
,
key
,
params
.
get
(
key
));
}
}
}
/**
* 替换表格文本
*
* @param tables
* @param params
*/
private
static
void
replaceTable
(
List
<
XWPFTable
>
tables
,
Map
<
String
,
String
>
params
)
{
for
(
XWPFTable
xwpfTable
:
tables
)
{
for
(
int
i
=
0
,
count
=
xwpfTable
.
getNumberOfRows
();
i
<
count
;
i
++)
{
XWPFTableRow
xwpfTableRow
=
xwpfTable
.
getRow
(
i
);
List
<
XWPFTableCell
>
xwpfTableCellList
=
xwpfTableRow
.
getTableCells
();
for
(
int
j
=
0
,
cellSize
=
xwpfTableCellList
.
size
();
j
<
cellSize
;
j
++)
{
XWPFTableCell
xwpfTableCell
=
xwpfTableCellList
.
get
(
j
);
List
<
XWPFParagraph
>
paragraphList
=
xwpfTableCell
.
getParagraphs
();
for
(
int
k
=
0
,
paragraphSize
=
paragraphList
.
size
();
k
<
paragraphSize
;
k
++)
{
XWPFParagraph
xwpfParagraph
=
paragraphList
.
get
(
k
);
if
(
Strings
.
isEmpty
(
xwpfParagraph
.
getText
()))
continue
;
for
(
String
key
:
params
.
keySet
())
{
if
(
xwpfParagraph
.
getText
().
contains
(
key
))
replaceInParagraph
(
xwpfParagraph
,
key
,
params
.
get
(
key
));
}
}
}
}
}
}
/**
* 段落内替换
*
* @param xwpfParagraph
* @param oldString
* @param newString
*/
private
static
void
replaceInParagraph
(
XWPFParagraph
xwpfParagraph
,
String
oldString
,
String
newString
)
{
List
<
XWPFRun
>
runs
=
xwpfParagraph
.
getRuns
();
int
runSize
=
runs
.
size
();
StringBuilder
textSb
=
new
StringBuilder
();
Map
<
Integer
,
String
>
textMap
=
new
HashMap
<>();
for
(
int
j
=
0
;
j
<
runSize
;
j
++)
{
XWPFRun
xwpfRun
=
runs
.
get
(
j
);
Integer
textPosition
=
xwpfRun
.
getTextPosition
();
String
text
=
xwpfRun
.
getText
(
textPosition
);
textSb
.
append
(
text
);
textMap
.
put
(
j
,
text
);
}
// 判断是否重合
if
(!
textSb
.
toString
().
contains
(
oldString
))
return
;
int
startIndex
=
0
;
int
mapSize
=
textMap
.
size
();
int
maxEndIndex
=
oldString
.
length
();
Integer
startPosition
=
null
,
endPosition
=
null
;
String
uuid
=
UUID
.
randomUUID
().
toString
();
alwaysFor:
for
(;
;
)
{
if
(
startIndex
>
mapSize
)
break
;
int
endIndex
=
startIndex
;
while
(
endIndex
>=
startIndex
&&
maxEndIndex
>
endIndex
-
startIndex
)
{
StringBuilder
strSb
=
new
StringBuilder
();
for
(
int
i
=
startIndex
;
i
<=
endIndex
;
i
++)
strSb
.
append
(
textMap
.
getOrDefault
(
i
,
uuid
));
if
(!
strSb
.
toString
().
trim
().
equals
(
oldString
))
++
endIndex
;
else
{
startPosition
=
startIndex
;
endPosition
=
endIndex
;
break
alwaysFor
;
}
}
++
startIndex
;
}
if
(
startPosition
!=
null
&&
endPosition
!=
null
)
{
XWPFRun
modelRun
=
runs
.
get
(
endPosition
);
XWPFRun
xwpfRun
=
xwpfParagraph
.
insertNewRun
(
endPosition
+
1
);
xwpfRun
.
setText
(
newString
);
if
(
modelRun
.
getFontSize
()
!=
-
1
)
{
xwpfRun
.
setFontSize
(
modelRun
.
getFontSize
());
}
xwpfRun
.
setFontFamily
(
modelRun
.
getFontFamily
());
//测试不删除变量
for
(
int
i
=
endPosition
;
i
>=
startPosition
;
i
--)
{
xwpfParagraph
.
removeRun
(
i
);
}
}
else
{
// 最小粒度无法匹配,此处采用下下策粗粒度替换文本
String
text
=
xwpfParagraph
.
getText
();
XWPFRun
xwpfRun
=
xwpfParagraph
.
getRuns
().
get
(
0
);
String
fontFamily
=
xwpfRun
.
getFontFamily
();
int
fontSize
=
xwpfRun
.
getFontSize
();
XWPFRun
insertXwpfRun
=
xwpfParagraph
.
insertNewRun
(
runSize
);
insertXwpfRun
.
setText
(
text
.
replace
(
oldString
,
newString
));
insertXwpfRun
.
setFontFamily
(
fontFamily
);
insertXwpfRun
.
setFontSize
(
fontSize
);
//测试不删除变量
for
(
int
i
=
runSize
-
1
;
i
>=
0
;
i
--)
{
xwpfParagraph
.
removeRun
(
i
);
}
}
}
/**
* 根据书签名替换为图片(只支持WORD2007)
*
* @param in
* @param out
* @param bookMarkName
* @param imageUrl
*/
public
static
void
replaceBookMarkByImage
(
InputStream
in
,
OutputStream
out
,
String
bookMarkName
,
String
imageUrl
,
InputStream
imgIn
)
throws
IOException
,
InvalidFormatException
{
XWPFDocument
document
=
new
XWPFDocument
(
in
);
List
<
XWPFParagraph
>
paragraphList
=
document
.
getParagraphs
();
for
(
XWPFParagraph
xwpfParagraph
:
paragraphList
)
{
CTP
ctp
=
xwpfParagraph
.
getCTP
();
for
(
int
dwI
=
0
;
dwI
<
ctp
.
sizeOfBookmarkStartArray
();
dwI
++)
{
CTBookmark
bookmark
=
ctp
.
getBookmarkStartArray
(
dwI
);
if
(
bookMarkName
.
equals
(
bookmark
.
getName
()))
{
XWPFRun
run
=
xwpfParagraph
.
createRun
();
Node
firstNode
=
bookmark
.
getDomNode
();
Node
nextNode
=
firstNode
.
getNextSibling
();
XWPFRun
runimg
=
xwpfParagraph
.
createRun
();
//FileInputStream imageStream = new FileInputStream(imageUrl);
byte
[]
bs
=
IOUtils
.
toByteArray
(
imgIn
);
BufferedImage
image
=
ImageIO
.
read
(
new
ByteArrayInputStream
(
bs
));
runimg
.
addPicture
(
new
ByteArrayInputStream
(
bs
),
Document
.
PICTURE_TYPE_JPEG
,
""
,
Units
.
toEMU
(
image
.
getWidth
()),
Units
.
toEMU
(
image
.
getHeight
()));
ctp
.
getDomNode
().
insertBefore
(
runimg
.
getCTR
().
getDomNode
(),
firstNode
);
//imageStream.close();
imgIn
.
close
();
}
}
}
document
.
write
(
out
);
return
;
}
public
static
void
replaceBookTag
(
XWPFDocument
document
,
Map
<
String
,
Object
>
bookTagMap
)
{
List
<
XWPFParagraph
>
paragraphList
=
document
.
getParagraphs
();
for
(
XWPFParagraph
xwpfParagraph
:
paragraphList
)
{
CTP
ctp
=
xwpfParagraph
.
getCTP
();
for
(
int
dwI
=
0
;
dwI
<
ctp
.
sizeOfBookmarkStartArray
();
dwI
++)
{
CTBookmark
bookmark
=
ctp
.
getBookmarkStartArray
(
dwI
);
if
(
bookTagMap
.
containsKey
(
bookmark
.
getName
()))
{
XWPFRun
run
=
xwpfParagraph
.
createRun
();
run
.
setText
(
bookTagMap
.
get
(
bookmark
.
getName
()).
toString
());
}
}
}
}
/**
* 将图片插入到word中
*
* @param inputDocPath:
* @param imagePath:
* @return void
*/
public
static
void
imageToWord
(
String
inputDocPath
,
String
outputDocPath
,
String
imagePath
)
{
try
{
// 加载现有的 Word 文档
com
.
aspose
.
words
.
Document
document
=
new
com
.
aspose
.
words
.
Document
(
inputDocPath
);
// 获取图片文件夹中的所有图片
File
folder
=
new
File
(
imagePath
);
File
[]
files
=
folder
.
listFiles
();
List
<
File
>
imageFiles
=
new
ArrayList
<
File
>();
for
(
File
file
:
files
)
{
if
(
file
.
isFile
()
&&
file
.
getName
().
toLowerCase
().
endsWith
(
".jpg"
))
{
imageFiles
.
add
(
file
);
}
}
// 插入图片并添加分页符
for
(
int
i
=
1
;
i
<=
imageFiles
.
size
();
i
++)
{
if
(
i
<
imageFiles
.
size
())
{
insertImage
(
document
,
imageFiles
.
get
(
i
-
1
).
getAbsolutePath
(),
true
);
document
.
getLastSection
().
getPageSetup
().
setSectionStart
(
SectionStart
.
NEW_PAGE
);
}
else
{
insertImage
(
document
,
imageFiles
.
get
(
i
-
1
).
getAbsolutePath
(),
false
);
}
}
// 保存新的 Word 文档
document
.
save
(
outputDocPath
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
/**
* 插入图片并分页
*
* @param document:
* @param imagePath:
* @param fenYe:
* @return void
*/
private
static
void
insertImage
(
com
.
aspose
.
words
.
Document
document
,
String
imagePath
,
Boolean
fenYe
)
throws
Exception
{
DocumentBuilder
builder
=
new
DocumentBuilder
(
document
);
// 移动光标到文档末尾
builder
.
moveToDocumentEnd
();
// 插入图片
builder
.
insertImage
(
imagePath
);
if
(
fenYe
)
{
// 添加分页符
builder
.
insertBreak
(
com
.
aspose
.
words
.
BreakType
.
PAGE_BREAK
);
}
}
private
static
String
getOutputDocPath
(
String
inputDocPath
)
{
int
dotIndex
=
inputDocPath
.
lastIndexOf
(
"."
);
String
fileName
=
inputDocPath
.
substring
(
0
,
dotIndex
);
String
extension
=
inputDocPath
.
substring
(
dotIndex
);
long
timeDifference
=
System
.
currentTimeMillis
()
-
new
File
(
inputDocPath
).
lastModified
();
return
fileName
+
"-"
+
timeDifference
+
extension
;
}
/**
* 以艺术字方式加上水印(平铺)
*
* @param docx XWPFDocument对象
* @param customText 水印文字
*/
public
static
void
makeFullWaterMarkByWordArt
(
XWPFDocument
docx
,
String
customText
,
String
fontColor
,
String
fontSize
,
String
styleRotation
)
{
// 水印文字之间使用8个空格分隔
customText
=
customText
+
repeatString
(
" "
,
16
);
// 一行水印重复水印文字次数
customText
=
repeatString
(
customText
,
10
);
// 与顶部的间距
String
styleTop
=
"0pt"
;
if
(
docx
==
null
)
{
return
;
}
// 遍历文档,添加水印
for
(
int
lineIndex
=
-
10
;
lineIndex
<
20
;
lineIndex
++)
{
styleTop
=
200
*
lineIndex
+
"pt"
;
waterMarkDocXDocument
(
docx
,
customText
,
styleTop
,
1
,
fontColor
,
fontSize
,
styleRotation
);
}
}
/**
* 将指定的字符串重复repeats次.
*
* @param pattern 字符串
* @param repeats 重复次数
* @return 生成的字符串
*/
private
static
String
repeatString
(
String
pattern
,
int
repeats
)
{
StringBuilder
buffer
=
new
StringBuilder
(
pattern
.
length
()
*
repeats
);
Stream
.
generate
(()
->
pattern
).
limit
(
repeats
).
forEach
(
buffer:
:
append
);
return
new
String
(
buffer
);
}
/**
* 为文档添加水印
* 实现参考了{@link XWPFHeaderFooterPolicy#(String, int)}
*
* @param doc 需要被处理的docx文档对象
* @param customText 水印文本
* @param type 类型:1.平铺;2.单个
*/
private
static
void
waterMarkDocXDocument
(
XWPFDocument
doc
,
String
customText
,
String
styleTop
,
int
type
,
String
fontColor
,
String
fontSize
,
String
rotation
)
{
//XWPFHeader header = doc.createHeader(HeaderFooterType.DEFAULT); // 如果之前已经创建过 DEFAULT 的Header,将会复用之
/* XWPFHeaderFooterPolicy headerFooterPolicy = doc.getHeaderFooterPolicy();
if (headerFooterPolicy == null) {
headerFooterPolicy = doc.createHeaderFooterPolicy();
}*/
// create default Watermark - fill color black and not rotated
//headerFooterPolicy.createWatermark(customText);
// get the default header
// Note: createWatermark also sets FIRST and EVEN headers
// but this code does not updating those other headers
//XWPFHeader header = headerFooterPolicy.getHeader(XWPFHeaderFooterPolicy.DEFAULT);
if
(
doc
.
getHeaderList
().
size
()
==
0
)
{
XWPFHeader
header
=
doc
.
createHeader
(
HeaderFooterType
.
DEFAULT
);
headerWatermark
(
doc
,
customText
,
styleTop
,
type
,
fontColor
,
fontSize
,
rotation
,
header
);
}
else
{
for
(
XWPFHeader
header
:
doc
.
getHeaderList
())
{
headerWatermark
(
doc
,
customText
,
styleTop
,
type
,
fontColor
,
fontSize
,
rotation
,
header
);
}
}
}
/**
* 处理Header水印
* @param doc
* @param customText
* @param styleTop
* @param type
* @param fontColor
* @param fontSize
* @param rotation
* @param header
*/
public
static
void
headerWatermark
(
XWPFDocument
doc
,
String
customText
,
String
styleTop
,
int
type
,
String
fontColor
,
String
fontSize
,
String
rotation
,
XWPFHeader
header
)
{
int
size
=
header
.
getParagraphs
().
size
();
if
(
size
==
0
)
{
header
.
createParagraph
();
}
CTP
ctp
=
header
.
getParagraphArray
(
0
).
getCTP
();
byte
[]
rsidr
=
doc
.
getDocument
().
getBody
().
getPArray
(
0
).
getRsidR
();
byte
[]
rsidrdefault
=
doc
.
getDocument
().
getBody
().
getPArray
(
0
).
getRsidRDefault
();
ctp
.
setRsidP
(
rsidr
);
ctp
.
setRsidRDefault
(
rsidrdefault
);
CTPPr
ppr
=
ctp
.
addNewPPr
();
ppr
.
addNewPStyle
().
setVal
(
"Header"
);
// 开始加水印
CTR
ctr
=
ctp
.
addNewR
();
CTRPr
ctrpr
=
ctr
.
addNewRPr
();
ctrpr
.
addNewNoProof
();
CTGroup
group
=
CTGroup
.
Factory
.
newInstance
();
CTShapetype
shapetype
=
group
.
addNewShapetype
();
CTTextPath
shapeTypeTextPath
=
shapetype
.
addNewTextpath
();
shapeTypeTextPath
.
setOn
(
STTrueFalse
.
T
);
shapeTypeTextPath
.
setFitshape
(
STTrueFalse
.
T
);
CTLock
lock
=
shapetype
.
addNewLock
();
lock
.
setExt
(
STExt
.
VIEW
);
CTShape
shape
=
group
.
addNewShape
();
shape
.
setId
(
"PowerPlusWaterMarkObject"
);
shape
.
setSpid
(
"_x0000_s102"
);
shape
.
setType
(
"#_x0000_t136"
);
// 平铺或单个
if
(
type
!=
2
)
{
// 设置形状样式(旋转,位置,相对路径等参数)
shape
.
setStyle
(
getShapeStyle
(
customText
,
styleTop
,
rotation
));
}
else
{
// 设置形状样式(旋转,位置,相对路径等参数)
shape
.
setStyle
(
getShapeStyle
());
}
shape
.
setFillcolor
(
fontColor
);
// 字体设置为实心
shape
.
setStroked
(
STTrueFalse
.
FALSE
);
// 绘制文本的路径
CTTextPath
shapeTextPath
=
shape
.
addNewTextpath
();
// 设置文本字体与大小
shapeTextPath
.
setStyle
(
"font-family:"
+
fontName
+
";font-size:"
+
fontSize
);
shapeTextPath
.
setString
(
customText
);
CTPicture
pict
=
ctr
.
addNewPict
();
pict
.
set
(
group
);
}
/**
* 构建Shape的样式参数
*
* @param customText 水印文本
* @return
*/
private
static
String
getShapeStyle
(
String
customText
,
String
styleTop
,
String
styleRotation
)
{
StringBuilder
sb
=
new
StringBuilder
();
// 文本path绘制的定位方式
sb
.
append
(
"position: "
).
append
(
"absolute"
);
// 计算文本占用的长度(文本总个数*单字长度)
sb
.
append
(
";width: "
).
append
(
customText
.
length
()
*
widthPerWord
).
append
(
"pt"
);
// 字体高度
sb
.
append
(
";height: "
).
append
(
"20pt"
);
sb
.
append
(
";z-index: "
).
append
(
"-251654144"
);
sb
.
append
(
";mso-wrap-edited: "
).
append
(
"f"
);
sb
.
append
(
";margin-top: "
).
append
(
styleTop
);
sb
.
append
(
";mso-position-horizontal-relative: "
).
append
(
"margin"
);
sb
.
append
(
";mso-position-vertical-relative: "
).
append
(
"margin"
);
sb
.
append
(
";mso-position-vertical: "
).
append
(
"left"
);
sb
.
append
(
";mso-position-horizontal: "
).
append
(
"center"
);
sb
.
append
(
";rotation: "
).
append
(
styleRotation
);
return
sb
.
toString
();
}
/**
* 构建Shape的样式参数
*
* @return
*/
private
static
String
getShapeStyle
()
{
StringBuilder
sb
=
new
StringBuilder
();
// 文本path绘制的定位方式
sb
.
append
(
"position: "
).
append
(
"absolute"
);
sb
.
append
(
";left: "
).
append
(
"opt"
);
// 计算文本占用的长度(文本总个数*单字长度)
sb
.
append
(
";width: "
).
append
(
"500pt"
);
// 字体高度
sb
.
append
(
";height: "
).
append
(
"150pt"
);
sb
.
append
(
";z-index: "
).
append
(
"-251654144"
);
sb
.
append
(
";mso-wrap-edited: "
).
append
(
"f"
);
sb
.
append
(
";margin-left: "
).
append
(
"-50pt"
);
sb
.
append
(
";margin-top: "
).
append
(
"270pt"
);
sb
.
append
(
";mso-position-horizontal-relative: "
).
append
(
"margin"
);
sb
.
append
(
";mso-position-vertical-relative: "
).
append
(
"margin"
);
sb
.
append
(
";mso-width-relative: "
).
append
(
"page"
);
sb
.
append
(
";mso-height-relative: "
).
append
(
"page"
);
sb
.
append
(
";rotation: "
).
append
(
"-2949120f"
);
return
sb
.
toString
();
}
/**
* 书签方式替换
* @param src
* @param dest
* @param docInfo
* @throws Exception
*/
public
static
void
replaceBookmark
(
String
src
,
String
dest
,
Map
<
String
,
String
>
docInfo
)
throws
Exception
{
com
.
aspose
.
words
.
Document
doc
=
new
com
.
aspose
.
words
.
Document
(
src
);
BookmarkCollection
bookmarks
=
doc
.
getRange
().
getBookmarks
();
for
(
String
bookMarkName
:
docInfo
.
keySet
())
{
Bookmark
bookmark
=
bookmarks
.
get
(
bookMarkName
);
if
(
bookmark
!=
null
)
{
// 页签包含list为动态表格数据
if
(
bookmark
.
getName
().
contains
(
"list"
))
{
// 动态插入word表格数据
Table
targetTable
=
(
Table
)
bookmark
.
getBookmarkStart
().
getParentNode
().
getParentNode
().
getParentNode
().
getParentNode
();
Row
targetRow
=
(
Row
)
bookmark
.
getBookmarkStart
().
getParentNode
().
getParentNode
().
getParentNode
();
// 复制表头后第一行
//Row cloneRow = (Row) targetTable.getRows().get(targetTable.indexOf(targetRow) + 1).deepClone(true);
List
<
Object
>
rowItem
=
new
ArrayList
<>();
Object
rowObj
=
docInfo
.
get
(
bookMarkName
);
if
(
rowObj
instanceof
List
)
{
rowItem
=
(
List
)
rowObj
;
}
for
(
int
i
=
0
;
i
<
rowItem
.
size
();
i
++)
{
// 复制表头后第一行
Row
cloneRow
=
(
Row
)
targetTable
.
getRows
().
get
(
targetTable
.
indexOf
(
targetRow
)
+
1
).
deepClone
(
true
);
List
<
String
>
cellList
=
(
List
<
String
>)
rowItem
.
get
(
i
);
for
(
int
j
=
0
;
j
<
cellList
.
size
();
j
++)
{
Cell
targetCell
=
cloneRow
.
getCells
().
get
(
j
);
targetCell
.
removeAllChildren
();
Paragraph
p
=
new
Paragraph
(
doc
);
p
.
appendChild
(
new
Run
(
doc
,
cellList
.
get
(
j
)));
// 设置居中对齐
p
.
getParagraphFormat
().
setAlignment
(
ParagraphAlignment
.
CENTER
);
targetCell
.
appendChild
(
p
);
targetCell
.
getCellFormat
().
setVerticalAlignment
(
VerticalAlignment
.
CENTER
);
targetCell
.
getCellFormat
().
setHorizontalMerge
(
HorizontalAlignment
.
CENTER
);
}
targetTable
.
getRows
().
insert
(
targetTable
.
indexOf
(
targetRow
)
+
1
+
i
,
cloneRow
);
}
}
else
{
bookmark
.
setText
(
docInfo
.
get
(
bookMarkName
));
}
}
FileOutputStream
out
=
new
FileOutputStream
(
dest
);
try
{
doc
.
save
(
out
,
SaveFormat
.
DOCX
);
}
catch
(
Exception
e
)
{
throw
e
;
}
finally
{
out
.
close
();
}
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment