-
准备需要的jar。
<!--生成word-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
-
controller层
@RequestMapping(value = {"/uploadWord/{id}"}, method = {RequestMethod.GET,RequestMethod.POST})
public void uploadWord(HttpServletResponse response,@PathVariable("id") Long id) throws Exception {
// 根据id,查询对应类型的报告
TdsmsOptSubscribe tdsmsOptSubscribe = subscribeService.selectTdsmsOptSubscribeById(id);
Optional.ofNullable(tdsmsOptSubscribe).orElseThrow(()-> new ServiceException("报告id["+id+"]不存在!"));
String wordPath = this.getClass().getClassLoader().getResource("word/").getPath();;
XWPFDocument xwpfDocument = null;
FileWordPdfEntity fileWordPdfEntity = null;
SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmssSSS");
String timestamp = format.format(new Date());
String fileName = tdsmsOptSubscribe.getSubscribeTitle()+"_"+timestamp;
// 文档类型
if (Objects.equals("1",tdsmsOptSubscribe.getSubscribeType())){
// linux下无法直接打开jar中模板的位置,必须把模板转换成输入流,生成临时文件再打开。
InputStream stream = this.getClass().getClassLoader().getResourceAsStream("word/surfTheInternet.docx");
wordPath+="surfTheInternetTmp.docx";
tmpFile(stream,wordPath);
fileWordPdfEntity = setFileWordPdfEntity(tdsmsOptSubscribe,wordPath);
xwpfDocument = iTdsmReportFormsService.downLoadFileWord(fileWordPdfEntity);
} else if (Objects.equals("3",tdsmsOptSubscribe.getSubscribeType())){
// linux下无法直接打开jar中模板的位置,必须把模板转换成输入流,生成临时文件再打开。
InputStream stream = this.getClass().getClassLoader().getResourceAsStream("word/fileSecurity.docx");
wordPath+="fileSecurityTmp.docx";
tmpFile(stream,wordPath);
fileWordPdfEntity = setFileWordPdfEntity(tdsmsOptSubscribe,wordPath);
xwpfDocument = iTdsmReportFormsService.downLoadSecurityWord(fileWordPdfEntity);
}
// 文档格式,如果是pdf,就需要把生成的word转换成pdf
if (Objects.equals("1",tdsmsOptSubscribe.getFileFormat())){
response.reset();
response.setContentType("application/octet-stream");
response.setCharacterEncoding("utf-8");
//response.setContentLength((int) xwpfDocument.length());
response.setHeader("Content-Disposition",
"attachment;filename=" + new String(fileName.getBytes("utf-8"), "ISO-8859-1") + ".docx");
OutputStream out = response.getOutputStream();
//将word对象内容写入输出流
xwpfDocument.write(out);
out.close();
} else {
// docx转换成pdf
String pdfPath = this.getClass().getClassLoader().getResource("word/").getPath();
//二进制OutputStream
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//文档写入流
xwpfDocument.write(baos);
//OutputStream写入InputStream二进制流
ByteArrayInputStream in = new ByteArrayInputStream(baos.toByteArray());
AsposeUtil bean = new AsposeUtil();
bean.word2pdf(pdfPath,in,tdsmsOptSubscribe.getSubscribeTitle()+timestamp);
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
FileUtils.setAttachmentResponseHeader(response,fileName+ ".pdf");
FileUtils.writeBytes(pdfPath + fileName + ".pdf",response.getOutputStream());
FileUtils.deleteFile(pdfPath + fileName + ".pdf");
}
// 更新订阅次数
Integer readNum = Objects.isNull(tdsmsOptSubscribe.getReadNum()) ? 0 : (tdsmsOptSubscribe.getReadNum() + 1);
tdsmsOptSubscribe.setReadNum(readNum);
subscribeMapper.updateById(tdsmsOptSubscribe);
}
/**
* 生成临时文件
* @param stream 文件输入流
* @param wordPath 临时文件地址
*/
public void tmpFile(InputStream stream, String wordPath) {
File file = new File(wordPath);
try {
//将读取到的类容存储到临时文件中,后面就可以用这个临时文件访问了
org.apache.commons.io.FileUtils.copyInputStreamToFile(stream,file);
} catch (IOException e) {
e.printStackTrace();
}
}
-
service层
package com.tdsms.busi.service.impl;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.tdsms.busi.domain.*;
import com.tdsms.busi.mapper.*;
import com.tdsms.busi.service.ITdsmReportFormsService;
import com.tdsms.busi.utils.CommonFileUtil;
import com.tdsms.common.minio.MinioUtil;
import com.tdsms.common.utils.DateUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.poi.ooxml.POIXMLDocument;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xddf.usermodel.chart.XDDFChartData;
import org.apache.poi.xddf.usermodel.chart.XDDFDataSource;
import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory;
import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.usermodel.XWPFChart;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collector;
import java.util.stream.Collectors;
@Service
public class TdsmReportFormsServiceImpl implements ITdsmReportFormsService {
@Autowired
private MinioUtil minioUtil;
@Autowired
private TdsmsAccountMapper tdsmsAccountMapper;
@Autowired
private TdsmsLogsSearchMapper tdsmsLogsSearchMapper;
@Autowired
private TdsmsLogsHtmlMapper tdsmsLogsHtmlMapper;
@Autowired
private TdsmsLogsImMsgMapper tdsmsLogsImMsgMapper;
@Autowired
private TdsmsLogsEmailMapper tdsmsLogsEmailMapper;
@Autowired
private TdsmsLogsFileSendMapper tdsmsLogsFileSendMapper;
@Autowired
private TdsmsLogsFileOptMapper tdsmsLogsFileOptMapper;
@Autowired
private TdsmsLogsScreenMapper tdsmsLogsScreenMapper;
@Autowired
private TdsmsLogsPrintMapper tdsmsLogsPrintMapper;
@Autowired
private TdsmsLogsClipboardMapper tdsmsLogsClipboardMapper;
@Override
public XWPFDocument downLoadFileWord(FileWordPdfEntity fileWordPdfEntity) throws IOException {
Map<String, String> map = new HashMap<String, String>();//把要替换的内容放入map
map.put("{startTime}", fileWordPdfEntity.getStartTime());
map.put("{endTime}", fileWordPdfEntity.getEndTime());
map.put("{nowTime}", DateUtils.getTime());
// List<TdsmsAccount> tdsmsAccountsOrgId = tdsmsAccountMapper.selectTdsmsAccountBatchListOrgIds(fileWordPdfEntity.getOrgIds());
List<TdsmsAccount> tdsmsAccountsUserId = tdsmsAccountMapper.selectTdsmsAccountBatchListUserIds(fileWordPdfEntity.getUserIdList());
//获取数据对象 用户名
Set<TdsmsAccount> userTotal = Sets.newHashSet();
for (TdsmsAccount tdsmsAccount : tdsmsAccountsUserId) {
userTotal.add(tdsmsAccount);
}
//统计总用户数量
map.put("{allUserTotal}", String.valueOf(fileWordPdfEntity.getUserIdList().size() ));
//统计新增用户数
List<TdsmsAccount> newInsertUserId = newInsertData(tdsmsAccountsUserId, fileWordPdfEntity.getStartTime(), fileWordPdfEntity.getEndTime());
map.put("{addUserTotal}", String.valueOf(newInsertUserId.size()));
// 日志查询值针对数据对象用户
String nameList = userTotal.stream().map(TdsmsAccount::getAccountName).distinct().collect(Collectors.joining(",", "", ""));
//搜索引擎日志查询
TdsmsLogsSearch tdsmsLogsSearch = new TdsmsLogsSearch();
tdsmsLogsSearch.setStartDate(fileWordPdfEntity.getStartTime());
tdsmsLogsSearch.setEndDate(fileWordPdfEntity.getEndTime());
tdsmsLogsSearch.setNameList(nameList);
List<TdsmsLogsSearch> tdsmsLogsSearches = tdsmsLogsSearchMapper.selectTdsmsLogsSearchList(tdsmsLogsSearch);
//网页浏览日志查询
TdsmsLogsHtml tdsmsLogsHtml = new TdsmsLogsHtml();
tdsmsLogsHtml.setStartDate(fileWordPdfEntity.getStartTime());
tdsmsLogsHtml.setEndDate(fileWordPdfEntity.getEndTime());
tdsmsLogsHtml.setNameList(nameList);
List<TdsmsLogsHtml> tdsmsLogsHtmls = tdsmsLogsHtmlMapper.selectTdsmsLogsHtmlList(tdsmsLogsHtml);
//即时通讯日志查询
TdsmsLogsImMsg tdsmsLogsImMsg = new TdsmsLogsImMsg();
tdsmsLogsImMsg.setStartDate(fileWordPdfEntity.getStartTime());
tdsmsLogsImMsg.setEndDate(fileWordPdfEntity.getEndTime());
tdsmsLogsImMsg.setNameList(nameList);
List<TdsmsLogsImMsg> tdsmsLogsImMsgs = tdsmsLogsImMsgMapper.selectTdsmsLogsImMsgList(tdsmsLogsImMsg);
//电子邮件日志查询
TdsmsLogsEmail tdsmsLogsEmail = new TdsmsLogsEmail();
tdsmsLogsEmail.setStartDate(fileWordPdfEntity.getStartTime());
tdsmsLogsEmail.setEndDate(fileWordPdfEntity.getEndTime());
tdsmsLogsEmail.setNameList(nameList);
List<TdsmsLogsEmail> tdsmsLogsEmails = tdsmsLogsEmailMapper.selectTdsmsLogsEmailList(tdsmsLogsEmail);
//统计日志总数
map.put("{logTotal}", String.valueOf(tdsmsLogsSearches.size() + tdsmsLogsHtmls.size() + tdsmsLogsImMsgs.size() + tdsmsLogsEmails.size()));
//告警日志总数
Integer alarmLogTotal = 0;
//告警用户数
LinkedHashMap<String, Integer> alarmUserTotal = Maps.newLinkedHashMap();
// 上网行为日志
LinkedHashMap<String, Integer> internetBehavior = Maps.newLinkedHashMap();
for (TdsmsLogsSearch logsSearch : tdsmsLogsSearches) {
if ("2".equals(logsSearch.getLogType())) {
// 统计告警日志总数
alarmLogTotal++;
// 统计告警用户数
if (alarmUserTotal.containsKey(logsSearch.getName())){
alarmUserTotal.put(logsSearch.getName(),alarmUserTotal.get(logsSearch.getName())+1);
} else {
alarmUserTotal.put(logsSearch.getName(),1);
}
}else {
// 统计用户上网行为
if (internetBehavior.containsKey(logsSearch.getName())){
internetBehavior.put(logsSearch.getName(),internetBehavior.get(logsSearch.getName())+1);
} else {
internetBehavior.put(logsSearch.getName(),1);
}
}
}
for (TdsmsLogsHtml logsHtml : tdsmsLogsHtmls) {
if ("2".equals(logsHtml.getLogType())) {
// 统计告警日志总数
alarmLogTotal++;
// 统计告警用户数
if (alarmUserTotal.containsKey(logsHtml.getName())){
alarmUserTotal.put(logsHtml.getName(),alarmUserTotal.get(logsHtml.getName())+1);
} else {
alarmUserTotal.put(logsHtml.getName(),1);
}
}else {
// 统计用户上网行为
if (internetBehavior.containsKey(logsHtml.getName())){
internetBehavior.put(logsHtml.getName(),internetBehavior.get(logsHtml.getName())+1);
} else {
internetBehavior.put(logsHtml.getName(),1);
}
}
}
for (TdsmsLogsImMsg logsImMsg : tdsmsLogsImMsgs) {
if ("2".equals(logsImMsg.getLogType())) {
// 统计告警日志总数
alarmLogTotal++;
// 统计告警用户数
if (alarmUserTotal.containsKey(logsImMsg.getName())){
alarmUserTotal.put(logsImMsg.getName(),alarmUserTotal.get(logsImMsg.getName())+1);
} else {
alarmUserTotal.put(logsImMsg.getName(),1);
}
} else {
// 统计用户上网行为
if (internetBehavior.containsKey(logsImMsg.getName())){
internetBehavior.put(logsImMsg.getName(),internetBehavior.get(logsImMsg.getName())+1);
} else {
internetBehavior.put(logsImMsg.getName(),1);
}
}
}
for (TdsmsLogsEmail logsEmail : tdsmsLogsEmails) {
if ("2".equals(logsEmail.getLogType())) {
// 统计告警日志总数
alarmLogTotal++;
// 统计告警用户数
if (alarmUserTotal.containsKey(logsEmail.getName())){
alarmUserTotal.put(logsEmail.getName(),alarmUserTotal.get(logsEmail.getName())+1);
} else {
alarmUserTotal.put(logsEmail.getName(),1);
}
} else {
// 统计用户上网行为
if (internetBehavior.containsKey(logsEmail.getName())){
internetBehavior.put(logsEmail.getName(),internetBehavior.get(logsEmail.getName())+1);
} else {
internetBehavior.put(logsEmail.getName(),1);
}
}
}
map.put("{alarmLogTotal}",String.valueOf(alarmLogTotal));
map.put("{alarmUserTotal}",String.valueOf(alarmUserTotal.values().stream().reduce(0,Integer::sum)));
OPCPackage pack = POIXMLDocument.openPackage(fileWordPdfEntity.getFilePath());//打开word模板文件
XWPFDocument document = new XWPFDocument(pack);//创建word对象
// 替换图表数据
List<XWPFChart> charts = document.getCharts();
// 告警用户 取前10
alarmUserTotal = top10(alarmUserTotal);
// 对用户上网行为 取前10
internetBehavior = top10(internetBehavior);
// 对用户网页浏览 group by 分组 然后排序 取前10
NavigableMap<String, List<TdsmsLogsHtml>> logsHtmls = tdsmsLogsHtmls.stream().collect(Collectors.groupingBy(TdsmsLogsHtml::getName,TreeMap::new, Collectors.toList())).descendingMap();
// 对用户搜索引擎 group by 分组 然后排序 取前10
NavigableMap<String, List<TdsmsLogsSearch>> logsSearches = tdsmsLogsSearches.stream().collect(Collectors.groupingBy(TdsmsLogsSearch::getName,TreeMap::new, Collectors.toList())).descendingMap();
// 对用户电子邮件 group by 分组 然后排序 取前10
NavigableMap<String, List<TdsmsLogsEmail>> logsEmails = tdsmsLogsEmails.stream().collect(Collectors.groupingBy(TdsmsLogsEmail::getName,TreeMap::new, Collectors.toList())).descendingMap();
// 对用户即时通讯 group by 分组 然后排序 取前10
NavigableMap<String, List<TdsmsLogsImMsg>> logsImMsgs = tdsmsLogsImMsgs.stream().collect(Collectors.groupingBy(TdsmsLogsImMsg::getName,TreeMap::new, Collectors.toList())).descendingMap();
chartsReplace(charts,alarmUserTotal,internetBehavior,top10(logsSearches),top10(logsHtmls),top10(logsImMsgs),top10(logsEmails));
CommonFileUtil.replaceStrs(document, map);//替换内容
//将XWPFDocument文件变为MultipartFile
// MultipartFile file = xwpfDocumentToCommonsMultipartFile(document, fileWordPdfEntity.getFileName()+".docx");
//上传文件到minio
// minioUtil.upload(file);
return document;
}
@Override
public XWPFDocument downLoadSecurityWord(FileWordPdfEntity fileWordPdfEntity) throws IOException {
Map<String, String> map = new HashMap<String, String>();//把要替换的内容放入map
map.put("{startTime}", fileWordPdfEntity.getStartTime());
map.put("{endTime}", fileWordPdfEntity.getEndTime());
map.put("{nowTime}", DateUtils.getTime());
List<TdsmsAccount> tdsmsAccountsUserId = tdsmsAccountMapper.selectTdsmsAccountBatchList(fileWordPdfEntity.getUserIdList());
//获取数据对象 用户名
Set<TdsmsAccount> userTotal = Sets.newHashSet();
for (TdsmsAccount tdsmsAccount : tdsmsAccountsUserId) {
userTotal.add(tdsmsAccount);
}
//统计总用户数量
map.put("{allUserTotal}", String.valueOf(fileWordPdfEntity.getUserIdList().size() ));
//统计新增用户数
List<TdsmsAccount> newInsertUserId = newInsertData(tdsmsAccountsUserId, fileWordPdfEntity.getStartTime(), fileWordPdfEntity.getEndTime());
map.put("{addUserTotal}", String.valueOf(newInsertUserId.size()));
// 日志查询值针对数据对象用户
String nameList = userTotal.stream().map(TdsmsAccount::getAccountName).distinct().collect(Collectors.joining(",", "", ""));
// 文件外发
TdsmsLogsFileSend tdsmsLogsFileSend = new TdsmsLogsFileSend();
tdsmsLogsFileSend.setStartDate(fileWordPdfEntity.getStartTime());
tdsmsLogsFileSend.setEndDate(fileWordPdfEntity.getEndTime());
tdsmsLogsFileSend.setNameList(nameList);
List<TdsmsLogsFileSend> tdsmsLogsFileSends = tdsmsLogsFileSendMapper.selectTdsmsLogsFileSendList(tdsmsLogsFileSend);
// 文档操作
TdsmsLogsFileOpt tdsmsLogsFileOpt = new TdsmsLogsFileOpt();
tdsmsLogsFileOpt.setStartDate(fileWordPdfEntity.getStartTime());
tdsmsLogsFileOpt.setEndDate(fileWordPdfEntity.getEndTime());
tdsmsLogsFileOpt.setNameList(nameList);
List<TdsmsLogsFileOpt> tdsmsLogsFileOpts = tdsmsLogsFileOptMapper.selectTdsmsLogsFileOptList(tdsmsLogsFileOpt);
// 屏幕审计
TdsmsLogsScreen tdsmsLogsScreen = new TdsmsLogsScreen();
tdsmsLogsScreen.setStartDate(fileWordPdfEntity.getStartTime());
tdsmsLogsScreen.setEndDate(fileWordPdfEntity.getEndTime());
tdsmsLogsScreen.setNameList(nameList);
List<TdsmsLogsScreen> tdsmsLogsScreens = tdsmsLogsScreenMapper.selectTdsmsLogsScreenList(tdsmsLogsScreen);
// 打印审计
TdsmsLogsPrint tdsmsLogsPrint = new TdsmsLogsPrint();
tdsmsLogsPrint.setStartDate(fileWordPdfEntity.getStartTime());
tdsmsLogsPrint.setEndDate(fileWordPdfEntity.getEndTime());
tdsmsLogsPrint.setNameList(nameList);
List<TdsmsLogsPrint> tdsmsLogsPrints = tdsmsLogsPrintMapper.selectTdsmsLogsPrintList(tdsmsLogsPrint);
// 剪贴板审计
TdsmsLogsClipboard tdsmsLogsClipboard = new TdsmsLogsClipboard();
tdsmsLogsClipboard.setStartDate(fileWordPdfEntity.getStartTime());
tdsmsLogsClipboard.setEndDate(fileWordPdfEntity.getEndTime());
tdsmsLogsClipboard.setNameList(nameList);
List<TdsmsLogsClipboard> tdsmsLogsClipboards = tdsmsLogsClipboardMapper.selectTdsmsLogsClipboardList(tdsmsLogsClipboard);
// 统计日志总数
map.put("{logTotal}", String.valueOf(tdsmsLogsFileSends.size() + tdsmsLogsFileOpts.size() + tdsmsLogsScreens.size() + tdsmsLogsPrints.size()) + tdsmsLogsClipboards.size());
// 告警日志总数
Integer alarmLogTotal = 0;
// 告警用户数
LinkedHashMap<String, Integer> alarmUserTotal = Maps.newLinkedHashMap();
// 用户文档审计日志统计
LinkedHashMap<String, Integer> auditStatistics= Maps.newLinkedHashMap();
for (TdsmsLogsFileSend logsFileSends : tdsmsLogsFileSends) {
if ("2".equals(logsFileSends.getLogType())) {
// 统计告警日志总数
alarmLogTotal++;
// 统计告警用户数
if (alarmUserTotal.containsKey(logsFileSends.getName())){
alarmUserTotal.put(logsFileSends.getName(),alarmUserTotal.get(logsFileSends.getName())+1);
} else {
alarmUserTotal.put(logsFileSends.getName(),1);
}
}else {
// 用户文档审计日志统计
if (auditStatistics.containsKey(logsFileSends.getName())){
auditStatistics.put(logsFileSends.getName(),auditStatistics.get(logsFileSends.getName())+1);
} else {
auditStatistics.put(logsFileSends.getName(),1);
}
}
}
for (TdsmsLogsFileOpt logsFileOpts : tdsmsLogsFileOpts) {
if ("2".equals(logsFileOpts.getLogType())) {
// 统计告警日志总数
alarmLogTotal++;
// 统计告警用户数
if (alarmUserTotal.containsKey(logsFileOpts.getName())){
alarmUserTotal.put(logsFileOpts.getName(),alarmUserTotal.get(logsFileOpts.getName())+1);
} else {
alarmUserTotal.put(logsFileOpts.getName(),1);
}
}else {
// 用户文档审计日志统计
if (auditStatistics.containsKey(logsFileOpts.getName())){
auditStatistics.put(logsFileOpts.getName(),auditStatistics.get(logsFileOpts.getName())+1);
} else {
auditStatistics.put(logsFileOpts.getName(),1);
}
}
}
for (TdsmsLogsScreen logsLogsScreens : tdsmsLogsScreens) {
if ("2".equals(logsLogsScreens.getLogType())) {
// 统计告警日志总数
alarmLogTotal++;
// 统计告警用户数
if (alarmUserTotal.containsKey(logsLogsScreens.getName())){
alarmUserTotal.put(logsLogsScreens.getName(),alarmUserTotal.get(logsLogsScreens.getName())+1);
} else {
alarmUserTotal.put(logsLogsScreens.getName(),1);
}
} else {
// 用户文档审计日志统计
if (auditStatistics.containsKey(logsLogsScreens.getName())){
auditStatistics.put(logsLogsScreens.getName(),auditStatistics.get(logsLogsScreens.getName())+1);
} else {
auditStatistics.put(logsLogsScreens.getName(),1);
}
}
}
for (TdsmsLogsPrint logsLogsPrints : tdsmsLogsPrints) {
if ("2".equals(logsLogsPrints.getLogType())) {
// 统计告警日志总数
alarmLogTotal++;
// 统计告警用户数
if (alarmUserTotal.containsKey(logsLogsPrints.getName())){
alarmUserTotal.put(logsLogsPrints.getName(),alarmUserTotal.get(logsLogsPrints.getName())+1);
} else {
alarmUserTotal.put(logsLogsPrints.getName(),1);
}
} else {
// 用户文档审计日志统计
if (auditStatistics.containsKey(logsLogsPrints.getName())){
auditStatistics.put(logsLogsPrints.getName(),auditStatistics.get(logsLogsPrints.getName())+1);
} else {
auditStatistics.put(logsLogsPrints.getName(),1);
}
}
}
for (TdsmsLogsClipboard logsLogsClipboards : tdsmsLogsClipboards) {
if ("2".equals(logsLogsClipboards.getLogType())) {
// 统计告警日志总数
alarmLogTotal++;
// 统计告警用户数
if (alarmUserTotal.containsKey(logsLogsClipboards.getName())){
alarmUserTotal.put(logsLogsClipboards.getName(),alarmUserTotal.get(logsLogsClipboards.getName())+1);
} else {
alarmUserTotal.put(logsLogsClipboards.getName(),1);
}
} else {
// 用户文档审计日志统计
if (auditStatistics.containsKey(logsLogsClipboards.getName())){
auditStatistics.put(logsLogsClipboards.getName(),auditStatistics.get(logsLogsClipboards.getName())+1);
} else {
auditStatistics.put(logsLogsClipboards.getName(),1);
}
}
}
map.put("{alarmLogTotal}",String.valueOf(alarmLogTotal));
map.put("{alarmUserTotal}",String.valueOf(alarmUserTotal.values().stream().reduce(0,Integer::sum)));
OPCPackage pack = POIXMLDocument.openPackage(fileWordPdfEntity.getFilePath());//打开word模板文件
// POIXMLDocument.openPackage()
XWPFDocument document = new XWPFDocument(pack);//创建word对象
// 替换图表数据
List<XWPFChart> charts = document.getCharts();
// 告警用户 取前10
alarmUserTotal = top10(alarmUserTotal);
// 用户文档审计日志统计 取前10
auditStatistics = top10(auditStatistics);
// 对文件外发 group by 分组 然后排序 取前10
NavigableMap<String, List<TdsmsLogsFileSend>> logsFileSend = tdsmsLogsFileSends.stream().collect(Collectors.groupingBy(TdsmsLogsFileSend::getName,TreeMap::new, Collectors.toList())).descendingMap();
// 对文档操作 group by 分组 然后排序 取前10
NavigableMap<String, List<TdsmsLogsFileOpt>> logsFileOpt = tdsmsLogsFileOpts.stream().collect(Collectors.groupingBy(TdsmsLogsFileOpt::getName,TreeMap::new, Collectors.toList())).descendingMap();
// 对屏幕审计 group by 分组 然后排序 取前10
NavigableMap<String, List<TdsmsLogsScreen>> logsScreen = tdsmsLogsScreens.stream().collect(Collectors.groupingBy(TdsmsLogsScreen::getName,TreeMap::new, Collectors.toList())).descendingMap();
// 对打印审计 group by 分组 然后排序 取前10
NavigableMap<String, List<TdsmsLogsPrint>> logsPrint = tdsmsLogsPrints.stream().collect(Collectors.groupingBy(TdsmsLogsPrint::getName,TreeMap::new, Collectors.toList())).descendingMap();
// 对剪贴板审计 group by 分组 然后排序 取前10
NavigableMap<String, List<TdsmsLogsClipboard>> logsClipboard = tdsmsLogsClipboards.stream().collect(Collectors.groupingBy(TdsmsLogsClipboard::getName,TreeMap::new, Collectors.toList())).descendingMap();
chartsReplace(charts, alarmUserTotal, auditStatistics, top10(logsFileSend), top10(logsFileOpt), top10(logsScreen), top10(logsPrint), top10(logsClipboard));
CommonFileUtil.replaceStrs(document, map);//替换内容
//将XWPFDocument文件变为MultipartFile
// MultipartFile file = xwpfDocumentToCommonsMultipartFile(document, fileWordPdfEntity.getFileName()+".docx");
//上传文件到minio
// minioUtil.upload(file);
return document;
}
/**
*
* @param charts
* @param alarmUser 告警用户统计
* @param auditStatistics 用户文档审计日志统计
* @param logsFileSend 用户文件外发排名
* @param logsFileOpt 用户文档操作日志
* @param logsScreen 用户屏幕审计日志
* @param logsPrint 用户打印审计日志
* @param logsClipboard 用户截切板审计日志
*/
private void chartsReplace(List<XWPFChart> charts, LinkedHashMap<String, Integer> alarmUser, LinkedHashMap<String, Integer> auditStatistics,
Map<String, Integer> logsFileSend, Map<String, Integer> logsFileOpt, Map<String, Integer> logsScreen,
Map<String, Integer> logsPrint, Map<String, Integer> logsClipboard) {
List<XWPFChart> sortListForXWPFChart = getSortListForXWPFChart(charts);
xWPFChartReplace(sortListForXWPFChart.get(0),alarmUser);
xWPFChartReplace(sortListForXWPFChart.get(1),auditStatistics);
xWPFChartReplace(sortListForXWPFChart.get(2),logsFileSend);
xWPFChartReplace(sortListForXWPFChart.get(3),logsFileOpt);
xWPFChartReplace(sortListForXWPFChart.get(4),logsScreen);
xWPFChartReplace(sortListForXWPFChart.get(5),logsPrint);
xWPFChartReplace(sortListForXWPFChart.get(6),logsClipboard);
}
private LinkedHashMap<String, Integer> top10(LinkedHashMap<String, Integer> alarmUserTotal) {
LinkedHashMap<String,Integer> alarmUsers = Maps.newLinkedHashMap();
// 转换成list
List<Map.Entry<String, Integer>> list = new ArrayList<>(alarmUserTotal.entrySet());
Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
// 降序排序
@Override
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
return o2.getValue().compareTo(o1.getValue());
}
});
List<Map.Entry<String, Integer>> collect1 = list.stream().limit(10).collect(Collectors.toList());
for (Map.Entry<String, Integer> entry : collect1) {
alarmUsers.put(entry.getKey(),entry.getValue());
}
return alarmUsers;
}
public<T> Map<String ,Integer> top10(NavigableMap<String, List<T>> collect) {
Map<String ,Integer> countGroupBy = new HashMap<>();
LinkedHashMap<String,Integer> result = Maps.newLinkedHashMap();
collect.forEach((k,v) -> {
countGroupBy.put(k,v.size());
});
// 转换成list
List<Map.Entry<String, Integer>> list = new ArrayList<>(countGroupBy.entrySet());
Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
// 降序排序
@Override
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
return o2.getValue().compareTo(o1.getValue());
}
});
List<Map.Entry<String, Integer>> collect1 = list.stream().limit(10).collect(Collectors.toList());
for (Map.Entry<String, Integer> entry : collect1) {
System.out.println("Key=" + entry.getKey() + ", Value=" + entry.getValue());
result.put(entry.getKey(),entry.getValue());
}
return result;
}
public List<TdsmsAccount> newInsertData (List<TdsmsAccount> tdsmsAccounts,String startTime,String endTime) {
List<TdsmsAccount> tdsmsAccountsOrgIdAdd = Lists.newArrayList();
for (TdsmsAccount tdsmsAccount : tdsmsAccounts) {
Date startTimeDate = DateUtils.dateTime(DateUtils.YYYY_MM_DD, startTime);
Date endTimeDate = DateUtils.dateTime(DateUtils.YYYY_MM_DD, endTime);
if(startTimeDate.before(tdsmsAccount.getCreateTime()) && endTimeDate.after(tdsmsAccount.getCreateTime())) {
tdsmsAccountsOrgIdAdd.add(tdsmsAccount);
}
}
return tdsmsAccountsOrgIdAdd;
}
/**
*
* @param charts 查询上网行为图表前10名数据
* @param alarmUser 告警用户统计
* @param internetBehavior 用户上网行为次数
* @param tdsmsLogsSearches 用户搜索引擎排名
* @param tdsmsLogsHtmls 网页浏览排名
* @param tdsmsLogsImMsgs 即时通讯排名
* @param tdsmsLogsEmails 用户电子邮件排名
*/
public void chartsReplace(List<XWPFChart> charts, Map<String, Integer> alarmUser, Map<String, Integer> internetBehavior, Map<String, Integer> tdsmsLogsSearches
, Map<String, Integer> tdsmsLogsHtmls, Map<String, Integer> tdsmsLogsImMsgs, Map<String, Integer> tdsmsLogsEmails) {
List<XWPFChart> sortListForXWPFChart = getSortListForXWPFChart(charts);
xWPFChartReplace(sortListForXWPFChart.get(0),alarmUser);
xWPFChartReplace(sortListForXWPFChart.get(1),internetBehavior);
xWPFChartReplace(sortListForXWPFChart.get(2),tdsmsLogsHtmls);
xWPFChartReplace(sortListForXWPFChart.get(3),tdsmsLogsSearches);
xWPFChartReplace(sortListForXWPFChart.get(4),tdsmsLogsEmails);
xWPFChartReplace(sortListForXWPFChart.get(5),tdsmsLogsImMsgs);
}
public void xWPFChartReplace (XWPFChart chart, Map<String, Integer> data) {
try{
//排序
//获取第一个图表
XSSFWorkbook workbook1 = chart.getWorkbook();
XSSFSheet sheet1 = workbook1.getSheetAt(0);
AtomicReference<Integer> count = new AtomicReference<>(0);
if (data.size() > 0) {
data.forEach((k, v) -> {
count.getAndSet(count.get() + 1);
if(count.get() <= data.size()){
xSSFSheetReplace(sheet1, count.get(), k, v);
}
});
}
// //因为原模板中 只插入了一行数据,所以这里需要用createCell方法新建一个单元格,直接getCell会报空指针
// XSSFCell cell20 = sheet1.getRow(2).getCell(0);
// cell20.setCellValue("李四");
// XSSFCell cell21 = sheet1.getRow(2).getCell(1);
// cell21.setCellValue(38);
XDDFChartData chartData1 = chart.getChartSeries().get(0);
XDDFChartData.Series s1 = chartData1.getSeries().get(0);
XDDFDataSource cat1 = XDDFDataSourcesFactory.fromStringCellRange(sheet1,
new CellRangeAddress(1, 10
, 0, 0));
XDDFNumericalDataSource val1 = XDDFDataSourcesFactory.fromNumericCellRange(sheet1,
new CellRangeAddress(1, 10, 1, 1));
s1.replaceData(cat1, val1);
// chart1.setTitleText("替换图表测试");
chart.plot(chartData1);
}catch (IOException e) {
e.printStackTrace();
} catch (InvalidFormatException e) {
e.printStackTrace();
}
}
public void xSSFSheetReplace(XSSFSheet sheet, Integer count, String name, Integer value) {
XSSFCell cell01 = sheet.getRow(count).createCell(0);
cell01.setCellValue(name);
XSSFCell cell02 = sheet.getRow(count).createCell(1);
cell02.setCellValue(value);
}
/**
* XWPFDocument 转 MultipartFile(CommonsMultipartFile)
*
* @param document 文档对象
* @param fileName 文件名
* @return
*/
public static MultipartFile xwpfDocumentToCommonsMultipartFile(XWPFDocument document, String fileName) {
//XWPFDocument转FileItem
FileItemFactory factory = new DiskFileItemFactory(16, null);
FileItem fileItem = factory.createItem("textField", "text/plain", true, fileName);
try {
OutputStream os = fileItem.getOutputStream();
document.write(os);
os.close();
//FileItem转MultipartFile
MultipartFile multipartFile = new CommonsMultipartFile(fileItem);
return multipartFile;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 对图表List重新排序
* @param affCharts doc.getCharts()
* @return
*/
public List<XWPFChart> getSortListForXWPFChart(List<XWPFChart> affCharts) {
List<XWPFChart> charts = new ArrayList<>();
int itNumber = 0; //计数器
int oldNumber = 0; //入参计数器
while (itNumber < affCharts.size()){
// 从oldCharts.get(0)开始检索,获取排序用图表名
String name = affCharts.get(oldNumber).getPackagePart().getPartName().toString();
// 获取此图表排序
String chartsNum = "";// 图表序号
boolean flag = false; // 上一个是否为数字
for (int i = 0; i < name.length(); i++) {
if (chartsNum.equals("") && name.charAt(i)>=48 && name.charAt(i)<=57 ){
chartsNum += name.charAt(i);
flag = true;
}else if ( flag && name.charAt(i)>=48 && name.charAt(i)<=57){
chartsNum += name.charAt(i);
flag = true;
}else {
flag = false;
}
}
//对比图表序号数字
int thisChartNum = Integer.parseInt(chartsNum);
if (thisChartNum == itNumber+1){ //如果相等则加入返回list,且itNumber++
charts.add(affCharts.get(oldNumber));
itNumber++;
}
//入参计数器+1 如果达到最大值则重置为0
if (oldNumber == affCharts.size()-1){
oldNumber = 0;
}else{
oldNumber++;
}
}
return charts;
}
}
-
CommonFileUtil帮助类
package com.tdsms.busi.utils;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import java.math.BigInteger;
import java.util.*;
/**
* 公共文件类
* */
public class CommonFileUtil {
/**
* 替换文档中的内容
* @param document 文档对象
* @param map 数据集合
* */
public static void replaceStrs(XWPFDocument document, Map<String,String> map){
replaceStrs(document, map,null);
}
/**
* 替换文档中的内容
* @param document 文档对象
* @param map 数据集合
* @param list 显示下划线的key集合
* */
public static void replaceStrs(XWPFDocument document, Map<String,String> map, List<String> list){
/**
* 对段落中的标记进行替换
*/
List<XWPFParagraph> parasList = document.getParagraphs();
replaceInAllParagraphs(parasList, map);
replaceTableStrs(document, map,list);
}
/**
* 替换段落中的内容
* @param document 文档对象
* @param map 数据集合
* @param list 显示下划线的key集合
* @param breaks 多行显示的key集合
* @param separator 分隔符
* @param replaceList 使用指定存在函数替换为key集合
* */
public static void replaceParagraphStrs(XWPFDocument document,Map<String,String> map,List<String> list,
List<String> breaks,String separator,List<String> replaceList){
replaceParagraphStrs(document, map, list, breaks, separator, replaceList,null,null,null,null,null);
}
/**
* 替换段落中的内容
* @param document 文档对象
* @param map 数据集合
* @param list 显示下划线的key集合
* @param breaks 多行显示的key集合
* @param separator 分隔符
* @param replaceList 使用指定存在函数替换为key集合
* @param fontFamily 字体
* @param fontSize 文字大小
* @param fontBold 是否加粗
* @param showLine 是否显示下划线
* @param removeList 要删除标题的内容key集合
* */
public static void replaceParagraphStrs(XWPFDocument document,Map<String,String> map,List<String> list,
List<String> breaks,String separator,List<String> replaceList,String fontFamily,Integer fontSize,
Boolean fontBold,Boolean showLine,List<String> removeList){
boolean removeTag=false;
if(removeList!=null&&removeList.size()>0){
removeTag=true;
}
boolean replaceTag=false;
if(replaceList!=null&&replaceList.size()>0){
replaceTag=true;
}
boolean flag=false;
if(list!=null&&list.size()>0){
flag=true;
}
boolean flags=false;
if(breaks!=null&&breaks.size()>0&&separator!=null&&!"".equals(separator)){
flags=true;
}
Iterator<XWPFParagraph> itPara = document.getParagraphsIterator();
String mkey=null;
String temp=null;
Iterator<String> iterator = null;
XWPFRun xwpfRun=null;
while (itPara.hasNext()) {
boolean tag=false;
XWPFParagraph paragraph = (XWPFParagraph) itPara.next();
iterator = map.keySet().iterator();
while (iterator.hasNext()) {
mkey = iterator.next();
List<XWPFRun> run=paragraph.getRuns();
for(int i=0;i<run.size();i++){
xwpfRun=run.get(i);
temp=xwpfRun.getText(xwpfRun.getTextPosition());
if(temp!=null ){
boolean tgs=false;
if(replaceTag&&replaceList.contains(mkey)){
tgs=temp.trim().contains(mkey);
}else{
tgs=temp.trim().equals(mkey);
}
if(tgs&&removeTag&&removeList.contains(mkey)){
xwpfRun.removeBreak();
continue;
}
if(tgs){
if(flag&&list.contains(mkey)){//设置下划线属性
xwpfRun.setUnderline(UnderlinePatterns.DOT_DOT_DASH);
}
if(flags&&breaks.contains(mkey)){
xwpfRun.setText("",0);
tag=true;
break;
}else{
if(replaceTag&&replaceList.contains(mkey)){
xwpfRun.setText(replaceStrs(temp,map,replaceList),0);
}else{
xwpfRun.setText(map.get(mkey)==null?"":map.get(mkey),0);
}
if(fontFamily!=null&&!fontFamily.equals("")){
xwpfRun.setFontFamily("宋体");
}
if(fontSize!=null){
xwpfRun.setFontSize(fontSize);
}
if(fontBold!=null&&fontBold){
xwpfRun.setBold(true);
}
if(showLine!=null&&showLine){
xwpfRun.setUnderline(UnderlinePatterns.DOT_DOT_DASH);
}
}
}
}
}
if(tag){
tag=false;
if(map.get(mkey)!=null){
String[] sts=map.get(mkey).split(separator);
if(sts.length>0){
for (int j =0; j <= sts.length-1; j++) {
XWPFRun run_s = paragraph.insertNewRun(paragraph.getRuns().size()-1);
run_s.setText(sts[j]);
if(j<sts.length-1){
run_s.addBreak();
}
if(fontFamily!=null&&!fontFamily.equals("")){
run_s.setFontFamily("宋体");
}
if(fontSize!=null){
run_s.setFontSize(fontSize);
}
if(fontBold!=null&&fontBold){
xwpfRun.setBold(true);
}
if(showLine!=null&&showLine){
xwpfRun.setUnderline(UnderlinePatterns.DOT_DOT_DASH);
}
}
}
}
}
}
}
}
private static String replaceStrs(String strs,Map<String,String> map,List<String> replaceList){
String value="";
String key="";
for (int i = 0; i < replaceList.size(); i++) {
key=replaceList.get(i);
value=map.get(key);
if(value!=null){
strs=strs.replace(key, value);
}
}
return strs;
}
/**
* 替换表格中内容
* @param document 文档对象
* @param map 数据集合
* */
public static void replaceTableStrs(XWPFDocument document,Map<String,String> map){
replaceTableStrs(document, map, null);
}
/**
* 替换表格中内容
* @param document 文档对象
* @param map 数据集合
* @param list 显示下划线的key集合
* */
public static void replaceTableStrs(XWPFDocument document,Map<String,String> map,List<String> list){
replaceTableStrs(document, map, list, null, null);
}
/**
* 替换表格中内容
* @param document 文档对象
* @param map 数据集合
* @param list 显示下划线的key集合
* @param breaks 多行显示的key集合
* @param separator 分隔符
* */
public static void replaceTableStrs(XWPFDocument document,Map<String,String> map,List<String> list,
List<String> breaks,String separator){
replaceTableStrs(document, map, list, breaks, separator,null);
}
/**
* 替换表格中内容
* @param document 文档对象
* @param map 数据集合
* @param list 显示下划线的key集合
* @param breaks 多行显示的key集合
* @param separator 分隔符
* @param removes 删除指定key所在的表格行的key集合
* */
public static void replaceTableStrs(XWPFDocument document,Map<String,String> map,List<String> list,
List<String> breaks,String separator,List<String> removes){
replaceTableStrs(document, map, list, breaks, separator, removes,null,null);
}
/**
* 替换表格中内容
* @param document 文档对象
* @param map 数据集合
* @param list 显示下划线的key集合
* @param breaks 多行显示的key集合
* @param separator 分隔符
* @param removes 删除指定key所在的表格行的key集合
* @param tableIndex 指定的表格索引
* @param isHidden 是否隐藏表格边框
* */
public static void replaceTableStrs(XWPFDocument document,Map<String,String> map,List<String> list,
List<String> breaks,String separator,List<String> removes,Integer tableIndex,Boolean isHidden){
replaceTableStrs(document, map, list, breaks, separator, removes, tableIndex, isHidden,null);
}
/**
* 替换表格中内容
* @param document 文档对象
* @param map 数据集合
* @param list 显示下划线的key集合
* @param breaks 多行显示的key集合
* @param separator 分隔符
* @param removes 删除指定key所在的表格行的key集合
* @param tableIndex 指定的表格索引
* @param isHidden 是否隐藏表格边框
* @param boldList 要加粗的内容集合
* */
public static void replaceTableStrs(XWPFDocument document,Map<String,String> map,List<String> list,
List<String> breaks,String separator,List<String> removes,Integer tableIndex,Boolean isHidden,List<String> boldList){
if(isHidden==null){
isHidden=false;
}
boolean flag=false;
if(list!=null&&list.size()>0){
flag=true;
}
boolean flags=false;
if(breaks!=null&&breaks.size()>0&&separator!=null&&!"".equals(separator)){
flags=true;
}
removeTableRow(document, removes);
if(tableIndex!=null){
XWPFTable table=document.getTables().get(tableIndex);
tableControl(table, map, list, breaks, separator, removes, tableIndex, isHidden, flag, flags,boldList);
}else{
Iterator<XWPFTable> itTable = document.getTablesIterator();
while (itTable.hasNext()) {
XWPFTable table = (XWPFTable) itTable.next();
tableControl(table, map, list, breaks, separator, removes, tableIndex, isHidden, flag, flags,boldList);
}
}
}
private static String getBoldStr(String strs,List<String> boldList){
int count=boldList.size();
for (int i = 0; i < count; i++) {
if(strs.contains(boldList.get(i))){
return boldList.get(i);
}
}
return "";
}
private static void tableControl( XWPFTable table,Map<String,String> map,List<String> list,
List<String> breaks,String separator,List<String> removes,Integer tableIndex,Boolean isHidden,
boolean flag,boolean flags,List<String> boldList){
boolean tagBold=false;
if(boldList!=null&&boldList.size()>0){
tagBold=true;
}
if(isHidden){
controlTableBorder(table);
}
String mkey=null;
String mvalue=null;
String temp=null;
XWPFRun xwpfRun=null;
Iterator<String> iterator = null;
int rcount = table.getNumberOfRows();
for (int i = 0; i < rcount; i++) {
XWPFTableRow row = table.getRow(i);
List<XWPFTableCell> cells = row.getTableCells();
for (XWPFTableCell cell : cells) {
temp=cell.getText();
iterator = map.keySet().iterator();
while (iterator.hasNext()) {
mkey = iterator.next();
mvalue=map.get(mkey);
if(mvalue==null){
continue;
}
String s=temp.replace(mkey, mvalue).replace(mkey, mvalue);
List<XWPFParagraph> paras=cell.getParagraphs();
if(paras.size()>0){
for (XWPFParagraph para : paras) {
boolean tag=false;
// para.setAlignment(ParagraphAlignment.CENTER);
// para.setBorderBottom(Borders.DOUBLE);
// para.setBorderTop(Borders.DOUBLE);
// para.setBorderRight(Borders.DOUBLE);
// para.setBorderLeft(Borders.DOUBLE);
// para.setBorderBetween(Borders.SINGLE);
// para.setVerticalAlignment(TextAlignment.TOP);
List<XWPFRun> runs = para.getRuns();
for (int k=0; k<runs.size(); k++) {
xwpfRun=runs.get(k);
String ts=xwpfRun.getText(xwpfRun.getTextPosition());
if(ts!=null && ts.trim().equals(mkey)){
if(flag&&list.contains(mkey)){//设置下划线属性
// xwpfRun.setUnderline(UnderlinePatterns.DOT_DOT_DASH);
xwpfRun.setUnderline(UnderlinePatterns.SINGLE);
}
if(flags&&breaks.contains(mkey)){
xwpfRun.setText("",0);
tag=true;
break;
}else{
String tempValue=map.get(mkey);
if(tagBold){
String boldStr=getBoldStr(tempValue, boldList);
if(!boldStr.equals("")){
int a_1=tempValue.indexOf(boldStr);
String temps=tempValue.substring(a_1+boldStr.length());
xwpfRun.setBold(true);
xwpfRun.setFontFamily("Times New Roman");
xwpfRun.setFontSize(10);
xwpfRun.setText(boldStr, 0);
XWPFRun xwpf=para.createRun();
xwpf.setText(temps, 0);
}else{
xwpfRun.setText(tempValue,0);
}
}else{
xwpfRun.setText(tempValue,0);
}
}
}
}
if(tag){
tag=false;
String[] sts=map.get(mkey).split(separator);
for (int j =0; j <= sts.length-1; j++) {
XWPFRun run = para.insertNewRun(para.getRuns().size()-1);
// run.setText(sts[j]);
String tempValue=sts[j];
if(tagBold){
String boldStr=getBoldStr(tempValue, boldList);
if(!boldStr.equals("")){
int a_1=tempValue.indexOf(boldStr);
String temps=tempValue.substring(a_1+boldStr.length());
run.setBold(true);
xwpfRun.setFontFamily("Times New Roman");
xwpfRun.setFontSize(10);
xwpfRun.setText(boldStr, 0);
run.setText(boldStr);
run=para.insertNewRun(para.getRuns().size()-1);
run.setText(temps);
}else{
run.setText(tempValue);
}
}else{
run.setText(tempValue);
}
if(j<sts.length-1){
run.addBreak();
}
// run.setFontFamily("宋体");
// run.setBold(true);
}
}
}
}else{
cell.setText(s);
}
}
}
}
}
private static void controlTableBorder(XWPFTable ss){
CTTblBorders borders=ss.getCTTbl().getTblPr().addNewTblBorders();
CTBorder hBorder=borders.addNewInsideH();
hBorder.setVal(STBorder.Enum.forString("none"));
hBorder.setSz(new BigInteger("1"));
hBorder.setColor("0000FF");
CTBorder vBorder=borders.addNewInsideV();
vBorder.setVal(STBorder.Enum.forString("none"));
vBorder.setSz(new BigInteger("1"));
vBorder.setColor("00FF00");
CTBorder lBorder=borders.addNewLeft();
lBorder.setVal(STBorder.Enum.forString("none"));
lBorder.setSz(new BigInteger("1"));
lBorder.setColor("3399FF");
CTBorder rBorder=borders.addNewRight();
rBorder.setVal(STBorder.Enum.forString("none"));
rBorder.setSz(new BigInteger("1"));
rBorder.setColor("F2B11F");
CTBorder tBorder=borders.addNewTop();
tBorder.setVal(STBorder.Enum.forString("none"));
tBorder.setSz(new BigInteger("1"));
tBorder.setColor("C3599D");
CTBorder bBorder=borders.addNewBottom();
bBorder.setVal(STBorder.Enum.forString("none"));
bBorder.setSz(new BigInteger("1"));
bBorder.setColor("F7E415");
}
/**
* 在指定表格中增加行
* @param document 文档对象
* @param tableIndex 表格索引
* @param rowIndex 行索引
* @param datas 行数据集合
* */
public static void addTableRow(XWPFDocument document,int tableIndex,Integer rowIndex,List<List<String>> datas){
addTableRow(document, tableIndex, rowIndex, datas,0);
}
/**
* 在指定表格中增加行
* @param document 文档对象
* @param tableIndex 表格索引
* @param rowIndex 行索引
* @param datas 行数据集合
* @param getRowIndex 获取指定行的列数据
* */
public static void addTableRow(XWPFDocument document,int tableIndex,Integer rowIndex,List<List<String>> datas,int getRowIndex){
addTableRow(document, tableIndex, rowIndex, datas, getRowIndex, null,null,null,null);
}
/**
* 在指定表格中增加行
* @param document 文档对象
* @param tableIndex 表格索引
* @param rowIndex 行索引
* @param datas 行数据集合
* @param getRowIndex 获取指定行的列数据
* @param align 布局方式
* @param num 次数
* @param fontFamily 字体
* @param fontSize 大小
* */
public static void addTableRow(XWPFDocument document,int tableIndex,Integer rowIndex,List<List<String>> datas,
int getRowIndex,String align,Integer num,String fontFamily,Integer fontSize){
if(align==null){
align="center";
}
boolean tag=false;
if(num!=null){
tag=true;
}
List<XWPFTable> ts=document.getTables();
XWPFTable ss=ts.get(tableIndex);
int c1=datas.size();
List<String> list=null;
XWPFTableRow rw=null;
for (int i = c1-1; i >=0; i--) {
list=datas.get(i);
if(rowIndex==null){
rowIndex=ss.getRows().size();
}
XWPFTableRow rws=ss.getRow(getRowIndex);
rw=ss.insertNewTableRow(rowIndex);
List<XWPFTableCell> rss=rws.getTableCells();
XWPFTableCell rs=null;
BigInteger width=BigInteger.valueOf(20);
for (int j = 0; j < rss.size(); j++) {
width= (BigInteger) rss.get(j).getCTTc().getTcPr().getTcW().getW();
rs=rw.addNewTableCell();
CTTcPr cellPr = rs.getCTTc().addNewTcPr();
cellPr.addNewVAlign().setVal(STVerticalJc.CENTER);
if(align.equals("center")){
}else if(align.equals("left")){
cellPr.addNewVAlign().setVal(STVerticalJc.TOP);
}else if(align.equals("right")){
cellPr.addNewVAlign().setVal(STVerticalJc.CENTER);
}
//设置宽度
cellPr.addNewTcW().setW(width);
XWPFParagraph p=null;
if(rs.getParagraphs().size()==0){
p=rs.addParagraph();
}else{
p=rs.getParagraphs().get(0);
}
if(align.equals("center")){
p.setAlignment(ParagraphAlignment.CENTER);
}else if(align.equals("left")){
p.setVerticalAlignment(TextAlignment.TOP);
p.setAlignment(ParagraphAlignment.LEFT);
}else if(align.equals("right")){
p.setAlignment(ParagraphAlignment.RIGHT);
}
XWPFRun r= p.createRun();
if(fontFamily!=null&&!"".equals(fontFamily)){
r.setFontFamily(fontFamily);
}
if(fontSize!=null&&fontSize>0){
r.setFontSize(fontSize);
}
if(!tag){
r.setText(list.get(j));
}
if(tag){
r.setText(list.get(j));
for (int k = 0; k < num; k++) {
r.addBreak();
}
}
}
}
}
/**
* 删除表格行
* @param document 文档对象
* @param key集合(存在删除行中的key)
* */
public static void removeTableRow(XWPFDocument document,List<String> list){
if(list==null||list.size()==0){
return;
}
String temp=null;
Iterator<XWPFTable> itTable = document.getTablesIterator();
Set<XWPFTableRow> rrows=null;
while (itTable.hasNext()) {
boolean tag=false;
XWPFTable table = (XWPFTable) itTable.next();
int rcount = table.getNumberOfRows();
rrows=new HashSet<XWPFTableRow>();
for (int i = 0; i < rcount; i++) {
XWPFTableRow row = table.getRow(i);
List<XWPFTableCell> cells = row.getTableCells();
for (XWPFTableCell cell : cells) {
temp=cell.getText();
for (String string : list) {
if(temp.contains(string)){
rrows.add(row);
tag=true;
}
}
}
}
if(tag){
iterationTable(table, rrows);
}
}
}
private static void iterationTable(XWPFTable table,Set<XWPFTableRow> rows ){
boolean tag=false;
int rcount = table.getNumberOfRows();
for (int i = 0; i < rcount; i++) {
XWPFTableRow row = table.getRow(i);
for (XWPFTableRow xwpfTableRow : rows) {
if(row.equals(xwpfTableRow)){
table.removeRow(i);
rows.remove(xwpfTableRow);
tag=true;
break;
}
}
if(tag){
break;
}
}
if(tag){
iterationTable(table, rows);
}
}
/**
* 替换所有段落中的标记
*
* @param xwpfParagraphList
* @param params
*/
public static void replaceInAllParagraphs(List<XWPFParagraph> xwpfParagraphList, Map<String, String> params) {
for (XWPFParagraph paragraph : xwpfParagraphList) {
if (paragraph.getText() == null || paragraph.getText().equals("")) continue;
for (String key : params.keySet()) {
if (paragraph.getText().contains(key)) {
replaceInParagraph(paragraph, key, params.get(key));
}
}
}
}
/**
* 替换段落中的字符串
*
* @param xwpfParagraph
* @param oldString
* @param newString
*/
public static void replaceInParagraph(XWPFParagraph xwpfParagraph, String oldString, String newString) {
Map<String, Integer> pos_map = findSubRunPosInParagraph(xwpfParagraph, oldString);
if (pos_map != null) {
// System.out.println("start_pos:" + pos_map.get("start_pos"));
// System.out.println("end_pos:" + pos_map.get("end_pos"));
List<XWPFRun> runs = xwpfParagraph.getRuns();
XWPFRun modelRun = runs.get(pos_map.get("end_pos"));
XWPFRun xwpfRun = xwpfParagraph.insertNewRun(pos_map.get("end_pos") + 1);
xwpfRun.setText(newString);
// System.out.println("字体大小:" + modelRun.getFontSize());
if (modelRun.getFontSize() != -1) xwpfRun.setFontSize(modelRun.getFontSize());//默认值是五号字体,但五号字体getFontSize()时,返回-1
xwpfRun.setFontFamily(modelRun.getFontFamily());
for (int i = pos_map.get("end_pos"); i >= pos_map.get("start_pos"); i--) {
// System.out.println("remove run pos in :" + i);
xwpfParagraph.removeRun(i);
}
}
}
/**
* 找到段落中子串的起始XWPFRun下标和终止XWPFRun的下标
*
* @param xwpfParagraph
* @param substring
* @return
*/
public static Map<String, Integer> findSubRunPosInParagraph(XWPFParagraph xwpfParagraph, String substring) {
List<XWPFRun> runs = xwpfParagraph.getRuns();
int start_pos = 0;
int end_pos = 0;
String subtemp = "";
for (int i = 0; i < runs.size(); i++) {
subtemp = "";
start_pos = i;
for (int j = i; j < runs.size(); j++) {
if (runs.get(j).getText(runs.get(j).getTextPosition()) == null) continue;
subtemp += runs.get(j).getText(runs.get(j).getTextPosition());
if (subtemp.equals(substring)) {
end_pos = j;
Map<String, Integer> map = new HashMap<>();
map.put("start_pos", start_pos);
map.put("end_pos", end_pos);
return map;
}
}
}
return null;
}
}
-
FileUtils帮助类
package com.tdsms.common.utils.file;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.tdsms.common.utils.uuid.IdUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ArrayUtils;
import com.tdsms.common.config.RuoYiConfig;
import com.tdsms.common.utils.DateUtils;
import com.tdsms.common.utils.StringUtils;
import org.apache.commons.io.FilenameUtils;
/**
* 文件处理工具类
*
* @author
*/
public class FileUtils
{
public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+";
/**
* 输出指定文件的byte数组
*
* @param filePath 文件路径
* @param os 输出流
* @return
*/
public static void writeBytes(String filePath, OutputStream os) throws IOException
{
FileInputStream fis = null;
try
{
File file = new File(filePath);
if (!file.exists())
{
throw new FileNotFoundException(filePath);
}
fis = new FileInputStream(file);
byte[] b = new byte[1024];
int length;
while ((length = fis.read(b)) > 0)
{
os.write(b, 0, length);
}
}
catch (IOException e)
{
throw e;
}
finally
{
IOUtils.close(os);
IOUtils.close(fis);
}
}
/**
* 输出指定文件的byte数组
*
* @param file 文件路径
* @param os 输出流
* @return
*/
public static void writeBytes(File file, OutputStream os) throws IOException
{
FileInputStream fis = null;
try
{
if (!file.exists())
{
throw new FileNotFoundException("pdf不存在");
}
fis = new FileInputStream(file);
byte[] b = new byte[1024];
int length;
while ((length = fis.read(b)) > 0)
{
os.write(b, 0, length);
}
}
catch (IOException e)
{
throw e;
}
finally
{
IOUtils.close(os);
IOUtils.close(fis);
}
}
/**
* 写数据到文件中
*
* @param data 数据
* @return 目标文件
* @throws IOException IO异常
*/
public static String writeImportBytes(byte[] data) throws IOException
{
return writeBytes(data, RuoYiConfig.getImportPath());
}
/**
* 写数据到文件中
*
* @param data 数据
* @param uploadDir 目标文件
* @return 目标文件
* @throws IOException IO异常
*/
public static String writeBytes(byte[] data, String uploadDir) throws IOException
{
FileOutputStream fos = null;
String pathName = "";
try
{
String extension = getFileExtendName(data);
pathName = DateUtils.datePath() + "/" + IdUtils.fastUUID() + "." + extension;
File file = FileUploadUtils.getAbsoluteFile(uploadDir, pathName);
fos = new FileOutputStream(file);
fos.write(data);
}
finally
{
IOUtils.close(fos);
}
return FileUploadUtils.getPathFileName(uploadDir, pathName);
}
/**
* 删除文件
*
* @param filePath 文件
* @return
*/
public static boolean deleteFile(String filePath)
{
boolean flag = false;
File file = new File(filePath);
// 路径为文件且不为空则进行删除
if (file.isFile() && file.exists())
{
file.delete();
flag = true;
}
return flag;
}
/**
* 文件名称验证
*
* @param filename 文件名称
* @return true 正常 false 非法
*/
public static boolean isValidFilename(String filename)
{
return filename.matches(FILENAME_PATTERN);
}
/**
* 检查文件是否可下载
*
* @param resource 需要下载的文件
* @return true 正常 false 非法
*/
public static boolean checkAllowDownload(String resource)
{
// 禁止目录上跳级别
if (StringUtils.contains(resource, ".."))
{
return false;
}
// 检查允许下载的文件规则
if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource)))
{
return true;
}
// 不在允许下载的文件规则
return false;
}
/**
* 下载文件名重新编码
*
* @param request 请求对象
* @param fileName 文件名
* @return 编码后的文件名
*/
public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException
{
final String agent = request.getHeader("USER-AGENT");
String filename = fileName;
if (agent.contains("MSIE"))
{
// IE浏览器
filename = URLEncoder.encode(filename, "utf-8");
filename = filename.replace("+", " ");
}
else if (agent.contains("Firefox"))
{
// 火狐浏览器
filename = new String(fileName.getBytes(), "ISO8859-1");
}
else if (agent.contains("Chrome"))
{
// google浏览器
filename = URLEncoder.encode(filename, "utf-8");
}
else
{
// 其它浏览器
filename = URLEncoder.encode(filename, "utf-8");
}
return filename;
}
/**
* 下载文件名重新编码
*
* @param response 响应对象
* @param realFileName 真实文件名
*/
public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException
{
String percentEncodedFileName = percentEncode(realFileName);
StringBuilder contentDispositionValue = new StringBuilder();
contentDispositionValue.append("attachment; filename=")
.append(percentEncodedFileName)
.append(";")
.append("filename*=")
.append("utf-8''")
.append(percentEncodedFileName);
response.addHeader("Access-Control-Expose-Headers", "Content-Disposition,download-filename");
response.setHeader("Content-disposition", contentDispositionValue.toString());
response.setHeader("download-filename", percentEncodedFileName);
}
/**
* 百分号编码工具方法
*
* @param s 需要百分号编码的字符串
* @return 百分号编码后的字符串
*/
public static String percentEncode(String s) throws UnsupportedEncodingException
{
String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());
return encode.replaceAll("\\+", "%20");
}
/**
* 获取图像后缀
*
* @param photoByte 图像数据
* @return 后缀名
*/
public static String getFileExtendName(byte[] photoByte)
{
String strFileExtendName = "jpg";
if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56)
&& ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97))
{
strFileExtendName = "gif";
}
else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70))
{
strFileExtendName = "jpg";
}
else if ((photoByte[0] == 66) && (photoByte[1] == 77))
{
strFileExtendName = "bmp";
}
else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71))
{
strFileExtendName = "png";
}
return strFileExtendName;
}
/**
* 获取文件名称 /profile/upload/2022/04/16/tt.png -- tt.png
*
* @param fileName 路径名称
* @return 没有文件路径的名称
*/
public static String getName(String fileName)
{
if (fileName == null)
{
return null;
}
int lastUnixPos = fileName.lastIndexOf('/');
int lastWindowsPos = fileName.lastIndexOf('\\');
int index = Math.max(lastUnixPos, lastWindowsPos);
return fileName.substring(index + 1);
}
/**
* 获取不带后缀文件名称 /profile/upload/2022/04/16/tt.png -- tt
*
* @param fileName 路径名称
* @return 没有文件路径和后缀的名称
*/
public static String getNameNotSuffix(String fileName)
{
if (fileName == null)
{
return null;
}
String baseName = FilenameUtils.getBaseName(fileName);
return baseName;
}
}
-
pdf生成帮助类
package com.tdsms.web.controller.tool;
import com.aspose.words.Document;
import com.aspose.words.FontSettings;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import java.io.*;
public class AsposeUtil {
/**
* 验证License 若不验证则转化出的pdf文档会有水印产生
* @return
*/
public boolean getLicense() {
boolean result = false;
try {
InputStream is =this.getClass().getClassLoader().getResourceAsStream("license.xml");
License aposeLic = new License();
aposeLic.setLicense(is);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
public static void main(String[] args) throws Exception {
AsposeUtil bean = new AsposeUtil();
bean.word2Pdf2("C:\\Users\\Rzxuser\\Downloads\\文档安全.docx","D:\\安全文档.pdf");
// bean.word2Pdf2("http://111.47.13.71:36038/tdsms/20230112-ffaa9d61-e8da-4443-bd01-755587a1655c.docx","D:\\test11.pdf");
/* XWPFDocument document = new XWPFDocument ();//新建文档 后面NEW方法可以忽略
ByteArrayOutputStream baos = new ByteArrayOutputStream();//二进制OutputStream
document.write(baos);//文档写入流
ByteArrayInputStream in = new ByteArrayInputStream(baos.toByteArray());//OutputStream写入InputStream二进制流
bean.word2pdf("D:\\test11",in,"test");*/
}
/**
* word转pdf
* inpath: 输入word的路径
* outpath: 输出pdf的路径
*/
public void word2Pdf2(String inpath,String outpath) throws Exception {
if (!getLicense()) {
System.out.println("非法------------");
return;
}
System.out.println("开始使用Aspose.words进行转换");
long old = System.currentTimeMillis();
File file = new File(outpath);
FileOutputStream os = new FileOutputStream(file);
//解决乱码
//如果是windows执行,不需要加这个
String osName = System.getProperty("os.name", "");
if (osName.startsWith("Mac OS")) {
} else if (osName.startsWith("Windows")) {
} else { // assume Unix or Linux
//如果是linux执行,需要添加这个 ,如果还有乱码,可以把/usr/share/fonts/chinese路径下的所有文件拷贝到有问题的环境。并且再执行:source /etc/profile
new FontSettings().setFontsFolder("/usr/share/fonts/chinese",true);
}
Document doc = new Document(inpath);
//全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换
doc.save(os, SaveFormat.PDF);
os.close();
long now = System.currentTimeMillis();
System.out.println("Aspose.words转换结束,共耗时:" + ((now - old) / 1000.0) + "秒");
}
/**
* word转pdf
* @param path pdf输出路径
* @param wordInput word输入流
* @param wordName word文档的名称
*/
public void word2pdf(String path, InputStream wordInput, String wordName) throws FileNotFoundException {
if (!getLicense()) {
System.out.println("非法");
return;
}
//新建一个空白pdf文档
long old = System.currentTimeMillis();
File file = new File(path + wordName + ".pdf");
FileOutputStream os = new FileOutputStream(file);
//解决乱码
//如果是windows执行,不需要加这个
String osName = System.getProperty("os.name", "");
if (osName.startsWith("Mac OS")) {
} else if (osName.startsWith("Windows")) {
} else { // assume Unix or Linux
//如果是linux执行,需要添加这个 ,如果还有乱码,可以把/usr/share/fonts/chinese路径下的所有文件拷贝到有问题的环境。并且再执行:source /etc/profile
new FontSettings().setFontsFolder("/usr/share/fonts/dejavu",true);
}
//Address是将要被转化的word文档
Document doc = null;
try {
doc = new Document(wordInput);
} catch (Exception e) {
e.printStackTrace();
}
try {
//全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换
doc.save(os, SaveFormat.PDF);
} catch (Exception e) {
e.printStackTrace();
}
long now = System.currentTimeMillis();
//转化用时
System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒");
}
}
-
效果图
模板
效果
-
docx转pdf需要jar和xml
<dependency>
<groupId>com.aspose.words</groupId>
<artifactId>aspose-words</artifactId>
<version>19.5</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/aspose-words-19.5.jar</systemPath>
</dependency>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.1.RELEASE</version>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
-
注意的坑
1、将word另存为xml文件(文件类型一定选择word xml文档),在编辑器中将变量写进去,然后存为docx。
2、word 模板,第一个图表最后一个用户数据 必须2空格呀!!!不然word转pdf的时候,x轴用户姓名会不显示的!!
3、需要把winds下的字体 拷贝到linux下面去,不然生成的pdf会有乱码。(https://blog.csdn.net/chengxuxuan/article/details/122827866?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-122827866-blog-64905214.pc_relevant_3mothn_strategy_recovery&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-122827866-blog-64905214.pc_relevant_3mothn_strategy_recovery&utm_relevant_index=1)
需要的jar包和xml
链接: https://pan.baidu.com/s/1euMsnp6oG7oFHrVE75B16w
提取码: dkde
版权声明:本文为CrushCoco原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。