Compare commits

..

5 Commits

Author SHA1 Message Date
copper
b6d04853ba prod 2021-05-25 19:03:01 +08:00
copper
aeb25715f1 fix project 2021-05-24 15:24:58 +08:00
copper
5e22ef0804 fix export bug 2021-05-23 16:55:59 +08:00
copper
cebef1294d 文件下载 2021-05-23 14:57:31 +08:00
copper
d51b387712 审计、时区 2021-05-22 14:00:16 +08:00
25 changed files with 665 additions and 100 deletions

2
.gitignore vendored
View File

@ -49,3 +49,5 @@ gen
hs_err_pid*
/upload/**
*.doc*

22
pom.xml
View File

@ -78,6 +78,28 @@
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>fr.opensagres.poi.xwpf.converter.core</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>fr.opensagres.xdocreport.itext.extension</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>fr.opensagres.poi.xwpf.converter.pdf</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>

View File

@ -76,9 +76,7 @@ public class AuthFilterConfig implements Filter {
}
String token = request.getHeader("Authorization");
if (uri.startsWith("/record/record2word")) {
token = request.getParameter("token");
}
if (token == null) {
log.error("请求无token");

View File

@ -11,6 +11,8 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @author Pope
@ -28,8 +30,13 @@ public class AuditController {
@RequestParam(value = "uri",required = false) String uri,
@RequestParam(value = "currentPage", defaultValue = "0") int currentPage,
@RequestParam(value = "pageSize", defaultValue = "30") int pageSize) {
Map<String, Object> resultMap = new HashMap<>(16,0.75F);
resultMap.put("totalCount", 100);
resultMap.put("currentPage", currentPage);
resultMap.put("pageSize", pageSize);
resultMap.put("data",auditService.listAuditLimit(beginTime, endTime, uri, currentPage, pageSize));
ResultVO resultVO = new ResultVO(ResultEnum.SUCCESS);
resultVO.setData(auditService.listAuditLimit(beginTime, endTime, uri, currentPage, pageSize));
resultVO.setData(resultMap);
return resultVO;
}

View File

@ -2,6 +2,7 @@ package com.example.survey.controller;
import com.example.survey.dto.project.AddRecordDTO;
import com.example.survey.dto.project.CreateProjectDTO;
import com.example.survey.dto.project.DeleteProjectDTO;
import com.example.survey.dto.project.DeleteRecordDTO;
import com.example.survey.dto.project.ModifyProjectDTO;
@ -64,6 +65,13 @@ public class ProjectController {
return new ResultVO(ResultEnum.SUCCESS);
}
@DeleteMapping("/project")
public ResultVO deleteProject(@RequestBody DeleteProjectDTO deleteProjectDTO){
projectService.deleteProject(deleteProjectDTO);
return new ResultVO(ResultEnum.SUCCESS);
}
@DeleteMapping("/record")
public ResultVO deleteRecord(@RequestBody DeleteRecordDTO deleteRecordDTO){
projectService.deleteRecord(deleteRecordDTO);

View File

@ -97,8 +97,16 @@ public class RecordController {
}
@GetMapping("/record2word")
public void record2word(@RequestParam("uuid") String uuid, HttpServletResponse response) {
recordService.record2word(uuid, response);
public ResultVO record2word(@RequestParam("uuid") String uuid) {
recordService.record2word(uuid);
ResultVO resultVO = new ResultVO(ResultEnum.SUCCESS);
return resultVO;
}
@GetMapping("/report")
public void report(@RequestParam("uuid") String uuid, HttpServletResponse response) {
// recordService.record2word(uuid, response);
recordService.report(uuid, response);
}
@PutMapping("/metaData")

View File

@ -55,4 +55,6 @@ public interface ProjectDao {
long countProject(String name, long date_gt, long date_lt);
void deleteProject(String name);
}

View File

@ -42,6 +42,7 @@ public class ProjectDaoImpl implements ProjectDao {
try {
mongoTemplate.save(project);
} catch (Exception e) {
// e.printStackTrace();
throw new ProjectException(ResultEnum.ALREADY_EXIST_PROJECT);
}
@ -53,12 +54,16 @@ public class ProjectDaoImpl implements ProjectDao {
if (name != null) {
criteria.and("name").regex(name);
}
if (date_gt != 0) {
criteria.and("date").gt(date_gt);
if (date_gt != 0 && date_lt != 0) {
// criteria.and("date").gt(date_gt).lt(date_lt);
criteria.andOperator(Criteria.where("date").gt(date_gt), Criteria.where("date").lt(date_lt));
}
if(date_lt != 0) {
else if(date_lt != 0) {
criteria.and("date").lt(date_lt);
}
else if (date_gt != 0) {
criteria.and("date").gt(date_gt);
}
Query query = new Query(criteria).skip(offset).limit(pageSize);
return mongoTemplate.find(query, Project.class);
}
@ -80,4 +85,12 @@ public class ProjectDaoImpl implements ProjectDao {
return mongoTemplate.count(query, Project.class);
}
@Override
public void deleteProject(String name) {
Query query = new Query();
query.addCriteria(Criteria.where("name").is(name));
mongoTemplate.remove(query, Project.class);
}
}

View File

@ -0,0 +1,12 @@
package com.example.survey.dto.project;
import lombok.Data;
import java.util.Date;
/**
* @author Pope
*/
@Data
public class DeleteProjectDTO {
private String name;
}

View File

@ -33,6 +33,7 @@ public class Project {
private long date;
@DBRef
private User user;
private long count;

View File

@ -20,6 +20,10 @@ public enum AuthEnum {
add("/project/projectState : PUT");
add("/project/project : PUT");
add("/project/project : POST");
add("/project/project : DELETE");
add("/project/record : DELETE");
add("/project/record : PUT");
add("/record/report : GET");
add("/respondent/respondent : POST");
add("/respondent/respondent : PUT");
@ -32,8 +36,10 @@ public enum AuthEnum {
add("/record/recordValues : GET");
add("/record/record : PUT");
add("/record/record : DELETE");
add("/record/underReviewRecord : PUT");
add("/record/review : PUT");
add("/record/metaData : PUT");
add("/record/file : POST");
add("/record/record2word : GET");
add("/user/userList : GET");
add("/user/user : POST");
@ -55,6 +61,8 @@ public enum AuthEnum {
add("/metaData/metaData : PUT");
add("/metaData/metaData : POST");
add("/metaData/wordTemplate : POST");
add("/audit/audit : GET");
}}),
/**
@ -63,15 +71,24 @@ public enum AuthEnum {
QUERY_PROJECT("查询项目的权限", new HashSet<String>() {{
add("/project/projectList : GET");
add("/project/respondentCount : GET");
add("/record/record2word : GET");
add("/record/report : GET");
}}),
MODIFY_PROJECT("修改项目的权限", new HashSet<String>() {{
add("/project/projectState : PUT");
add("/project/project : PUT");
add("/project/record : DELETE");
add("/project/record : PUT");
}}),
CREATE_PROJECT("创建项目的权限", new HashSet<String>() {{
add("/project/project : POST");
}}),
DELETE_PROJECT("删除项目的权限", new HashSet<String>() {{
add("/project/project : DELETE");
}}),
/**
* 调查对象
@ -105,11 +122,14 @@ public enum AuthEnum {
MODIFY_RECORD("修改流调记录的权限", new HashSet<String>() {{
add("/record/record : PUT");
}}),
RECORD_METADATA("修改流调记录元数据的权限", new HashSet<String>() {{
add("/record/metaData : PUT");
}}),
DELETE_RECORD("删除流调记录的权限", new HashSet<String>() {{
add("/record/record : DELETE");
}}),
EXAMINE_RECORD("审核流调记录的权限", new HashSet<String>() {{
add("/record/underReviewRecord : PUT");
add("/record/review : PUT");
}}),
UPLOAD_RECORD_FILE("上传流调记录相关文件的权限", new HashSet<String>() {{
add("/record/file : POST");
@ -164,7 +184,7 @@ public enum AuthEnum {
add("/metadata/metadata : PUT");
}}),
DELETE_METADATA("删除元数据的权限", new HashSet<String>() {{
add("/metadata/metadata : DELETE");
}}),
CREATE_METADATA("添加元数据的权限", new HashSet<String>() {{
add("/metadata/metadata : POST");
@ -177,7 +197,7 @@ public enum AuthEnum {
* 审计
*/
QUERY_AUDIT("查询审计记录", new HashSet<String>() {{
add("/audit/audit : GET");
}});
private String name;

View File

@ -2,6 +2,7 @@ package com.example.survey.service;
import com.example.survey.dto.project.AddRecordDTO;
import com.example.survey.dto.project.CreateProjectDTO;
import com.example.survey.dto.project.DeleteProjectDTO;
import com.example.survey.dto.project.DeleteRecordDTO;
import com.example.survey.dto.project.ModifyProjectDTO;
@ -56,6 +57,7 @@ public interface ProjectService {
*/
long countProject(String name, long date_gt, long date_lt);
void deleteProject(DeleteProjectDTO projectDTO);
void addRecord(AddRecordDTO addRecordDTO);

View File

@ -1,6 +1,7 @@
package com.example.survey.service;
import com.example.survey.dto.record.*;
import com.example.survey.vo.RecordDetailVO;
import com.example.survey.vo.RecordVO;
import org.springframework.web.multipart.MultipartFile;
@ -74,7 +75,7 @@ public interface RecordService {
* @param version 版本号
* @return 流调记录的values
*/
Map<String,Object> getRecordValues(String uuid);
RecordDetailVO getRecordValues(String uuid);
/**
* 上传文件
@ -98,9 +99,11 @@ public interface RecordService {
* @param projectName 项目名
* @param response 响应
*/
void record2word(String idNumber, HttpServletResponse response);
boolean record2word(String idNumber);
void report(String uuid, HttpServletResponse response);
/**
* 修改流调记录所绑定元数据
*

View File

@ -6,6 +6,7 @@ import com.example.survey.dao.RecordDao;
import com.example.survey.dao.UserDao;
import com.example.survey.dto.project.AddRecordDTO;
import com.example.survey.dto.project.CreateProjectDTO;
import com.example.survey.dto.project.DeleteProjectDTO;
import com.example.survey.dto.project.DeleteRecordDTO;
import com.example.survey.dto.project.ModifyProjectDTO;
@ -13,6 +14,7 @@ import com.example.survey.entity.MetaData;
import com.example.survey.entity.Project;
import com.example.survey.entity.Record;
import com.example.survey.entity.User;
import com.example.survey.enumeration.MetaDataTypeEnum;
import com.example.survey.enumeration.ProjectStateEnum;
import com.example.survey.enumeration.ResultEnum;
import com.example.survey.exception.MetaDataException;
@ -127,7 +129,10 @@ public class ProjectServiceImpl implements ProjectService {
t.add(project.getName());
record.setProjectList(t);
recordDao.saveRecord(record);
if(record.getMetaDataType().equals(MetaDataTypeEnum.RECORD_TEMP.getValue())) {
project.setCount(project.getCount() + 1);
}
projectDao.saveProject(project);
}
}
@ -156,11 +161,23 @@ public class ProjectServiceImpl implements ProjectService {
t.remove(project.getName());
record.setProjectList(t);
recordDao.saveRecord(record);
if(record.getMetaDataType().equals(MetaDataTypeEnum.RECORD_TEMP.getValue())) {
project.setCount(project.getCount() - 1);
}
projectDao.saveProject(project);
}
}
@Override
public void deleteProject(DeleteProjectDTO projectDTO) {
if(!projectDao.existProject(projectDTO.getName()))
{
throw new ProjectException(ResultEnum.NOT_EXIST_PROJECT);
}
projectDao.deleteProject(projectDTO.getName());
}
}

View File

@ -4,12 +4,16 @@ import com.example.survey.dao.*;
import com.example.survey.dto.record.*;
import com.example.survey.entity.*;
import com.example.survey.entity.inner.Operation;
import com.example.survey.enumeration.MetaDataTypeEnum;
import com.example.survey.enumeration.RecordStateEnum;
import com.example.survey.enumeration.ResultEnum;
import com.example.survey.exception.*;
import com.example.survey.service.RecordService;
import com.example.survey.util.DownloadUtil;
import com.example.survey.util.ThreadWordUtil;
import com.example.survey.util.WordUtil;
import com.example.survey.vo.RecordDetailVO;
import com.example.survey.vo.RecordVO;
import com.example.survey.vo.inner.OperationInfo;
import lombok.extern.log4j.Log4j2;
@ -51,6 +55,11 @@ public class RecordServiceImpl implements RecordService {
@Value("${file.url}")
private String url;
@Value("${file.report}")
private String report;
@Autowired
private ThreadWordUtil threadWordUtil;
@Override
public void reviewRecord(ReviewRecordDTO reviewRecordDTO) {
@ -64,7 +73,8 @@ public class RecordServiceImpl implements RecordService {
}
Record record = recordDao.getRecord(reviewRecordDTO.getUuid());
record.setState(reviewRecordDTO.getPass() ? RecordStateEnum.REVIEWED.getValue() : RecordStateEnum.NOT_PASS.getValue());
record.setState(
reviewRecordDTO.getPass() ? RecordStateEnum.REVIEWED.getValue() : RecordStateEnum.NOT_PASS.getValue());
// record.setVersion(UUID.randomUUID().toString());
Operation reviewOp = Operation.reviewOp(user, reviewRecordDTO.getMsg(), reviewRecordDTO.getPass());
List<Operation> opList = record.getOperationList();
@ -123,24 +133,30 @@ public class RecordServiceImpl implements RecordService {
}
@Override
public long countRecord(String idNumber, String state, String uuid,
String templateName, String templateType,
public long countRecord(String idNumber, String state, String uuid, String templateName, String templateType,
long submitTimeGt, long submitTimeLt, String projectName) {
return recordDao.countRecord(idNumber, state, uuid, templateName, templateType, submitTimeGt, submitTimeLt, projectName);
return recordDao.countRecord(idNumber, state, uuid, templateName, templateType, submitTimeGt, submitTimeLt,
projectName);
}
@Override
public List<RecordVO> listRecordLimit(String idNumber, String state, String uuid,
String templateName, String templateType,
long submitTimeGt, long submitTimeLt, String projectName, int currentPage, int pageSize) {
public List<RecordVO> listRecordLimit(String idNumber, String state, String uuid, String templateName,
String templateType, long submitTimeGt, long submitTimeLt, String projectName, int currentPage,
int pageSize) {
List<Record> recordList = recordDao.listRecordLimit(idNumber, state, uuid, templateName, templateType, submitTimeGt, submitTimeLt, projectName, currentPage * pageSize, pageSize);
List<Record> recordList = recordDao.listRecordLimit(idNumber, state, uuid, templateName, templateType,
submitTimeGt, submitTimeLt, projectName, currentPage * pageSize, pageSize);
return recordList.stream().map(record -> {
RecordVO recordVO = new RecordVO();
recordVO.setIdNumber(record.getIdNumber());
recordVO.setUuid(record.getUuid());
if (record.getMetaData() == null) {
recordVO.setTemplate(null);
} else {
recordVO.setTemplate(record.getMetaData().getName());
}
recordVO.setOperationInfoList(record.getOperationList().stream().map(op -> {
OperationInfo operationInfo = new OperationInfo();
operationInfo.setType(op.getType());
@ -151,6 +167,7 @@ public class RecordServiceImpl implements RecordService {
operationInfo.setResult(op.getResult());
return operationInfo;
}).collect(Collectors.toList()));
recordVO.setProjectList(record.getProjectList());
recordVO.setState(record.getState());
recordVO.setSubmitTime(record.getSubmitTime());
return recordVO;
@ -158,13 +175,36 @@ public class RecordServiceImpl implements RecordService {
}
@Override
public Map<String, Object> getRecordValues(String uuid) {
public RecordDetailVO getRecordValues(String uuid) {
Record record = recordDao.getRecord(uuid);
if (record == null) {
throw new RecordException(ResultEnum.NOT_EXIST_RECORD);
}
return record.getValues();
RecordDetailVO recordVO = new RecordDetailVO();
recordVO.setIdNumber(record.getIdNumber());
recordVO.setUuid(record.getUuid());
if (record.getMetaData() == null) {
recordVO.setTemplate(null);
} else {
recordVO.setTemplate(record.getMetaData().getName());
}
recordVO.setOperationInfoList(record.getOperationList().stream().map(op -> {
OperationInfo operationInfo = new OperationInfo();
operationInfo.setType(op.getType());
operationInfo.setTime(op.getTime());
operationInfo.setPersonId(op.getUser().getPhone());
operationInfo.setPersonName(op.getUser().getUsername());
operationInfo.setMsg(op.getMsg());
operationInfo.setResult(op.getResult());
return operationInfo;
}).collect(Collectors.toList()));
recordVO.setProjectList(record.getProjectList());
recordVO.setState(record.getState());
recordVO.setSubmitTime(record.getSubmitTime());
recordVO.setValues(record.getValues());
return recordVO;
}
@Override
@ -224,9 +264,23 @@ public class RecordServiceImpl implements RecordService {
}
@Override
public void record2word(String uuid, HttpServletResponse response) {
public boolean record2word(String uuid) {
Record record = recordDao.getRecord(uuid);
if(!record.getMetaDataType().equals(MetaDataTypeEnum.REPORT_TEMP.getValue())) {
throw new RecordException(ResultEnum.NOT_EXIST_RECORD);
}
if(record.getState().equals(RecordStateEnum.REVIEWED.getValue())) {
return true;
}
threadWordUtil.setRecord(record);
threadWordUtil.setThreadName(record.getUuid() + ":" + String.valueOf(System.currentTimeMillis()));
// ThreadWordUtil wordUtil = new ThreadWordUtil();
// wordUtil.setRecord(record);
// wordUtil.setThreadName(record.getUuid() + ":" + String.valueOf(System.currentTimeMillis()));
threadWordUtil.start();
return true;
}
@Override
@ -257,4 +311,29 @@ public class RecordServiceImpl implements RecordService {
recordDao.saveRecord(record);
}
@Override
public void report(String uuid, HttpServletResponse response) {
Record record = recordDao.getRecord(uuid);
if (record == null) {
throw new RecordException(ResultEnum.NOT_EXIST_RECORD);
}
if(!record.getMetaDataType().equals(MetaDataTypeEnum.REPORT_TEMP.getValue())) {
throw new RecordException(ResultEnum.NOT_EXIST_RECORD);
}
if(!record.getState().equals(RecordStateEnum.REVIEWED.getValue())){
throw new RecordException(ResultEnum.NOT_EXIST_RECORD);
}
String path = this.report + record.getUuid() + ".docx";
try {
DownloadUtil.downloadFile(path, response);
} catch (IOException e) {
response.setStatus(400);
// response.clo
}
}
}

View File

@ -0,0 +1,111 @@
package com.example.survey.util;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlToken;
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;
import fr.opensagres.poi.xwpf.converter.core.IXWPFConverter;
import fr.opensagres.poi.xwpf.converter.pdf.PdfConverter;
import fr.opensagres.poi.xwpf.converter.pdf.PdfOptions;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
*
* 版权声明本文为CSDN博主BlogTonycsdn的原创文章遵循 CC 4.0 BY-SA
* 版权协议转载请附上原文出处链接及本声明
* 原文链接https://blog.csdn.net/liyuzhuang/article/details/78094349 支持word2007+
* 插入图片
*
* @author liyuzhuang
*
*/
public class CustomXWPFDocument extends XWPFDocument {
public CustomXWPFDocument(InputStream in) throws IOException {
super(in);
}
public CustomXWPFDocument(OPCPackage pkg) throws IOException {
super(pkg);
}
public void createPicture(String blipId, int id, int width, int height, XWPFParagraph paragraph) {
final int EMU = 9525;
width *= EMU;
height *= EMU;
CTInline inline = paragraph.createRun().getCTR().addNewDrawing().addNewInline();
String picXml = "" + "<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">"
+ " <a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"
+ " <pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"
+ " <pic:nvPicPr>" + " <pic:cNvPr id=\"" + id + "\" name=\"Generated\"/>"
+ " <pic:cNvPicPr/>" + " </pic:nvPicPr>" + " <pic:blipFill>"
+ " <a:blip r:embed=\"" + blipId
+ "\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>"
+ " <a:stretch>" + " <a:fillRect/>" + " </a:stretch>"
+ " </pic:blipFill>" + " <pic:spPr>" + " <a:xfrm>"
+ " <a:off x=\"0\" y=\"0\"/>" + " <a:ext cx=\"" + width + "\" cy=\""
+ height + "\"/>" + " </a:xfrm>" + " <a:prstGeom prst=\"rect\">"
+ " <a:avLst/>" + " </a:prstGeom>" + " </pic:spPr>"
+ " </pic:pic>" + " </a:graphicData>" + "</a:graphic>";
// CTGraphicalObjectData graphicData =
// inline.addNewGraphic().addNewGraphicData();
XmlToken xmlToken = null;
try {
xmlToken = XmlToken.Factory.parse(picXml);
} catch (XmlException xe) {
xe.printStackTrace();
}
inline.set(xmlToken);
// graphicData.set(xmlToken);
inline.setDistT(0);
inline.setDistB(0);
inline.setDistL(0);
inline.setDistR(0);
CTPositiveSize2D extent = inline.addNewExtent();
extent.setCx(width);
extent.setCy(height);
CTNonVisualDrawingProps docPr = inline.addNewDocPr();
docPr.setId(id);
docPr.setName("Picture " + id);
docPr.setDescr("Generated");
}
public void convertToPDF(String output) throws IOException {
OutputStream out = null;
try{
throw(new Exception());
/**
* 格式错误 不能使用
*/
// PdfOptions pdfOptions = PdfOptions.create().fontEncoding("UTF-8");
// out = new FileOutputStream(output + ".pdf");
// IXWPFConverter<PdfOptions> converter = PdfConverter.getInstance();
// converter.convert(this, out, pdfOptions);
}
catch (Exception e) {
e.printStackTrace();
out = new FileOutputStream(output);
this.write(out);
}
finally {
if(out != null) {
out.close();
}
}
}
}

View File

@ -0,0 +1,27 @@
package com.example.survey.util;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.UUID;
import javax.servlet.http.HttpServletResponse;
public class DownloadUtil {
public static void downloadFile(String path, HttpServletResponse response) throws IOException {
response.addHeader("Content-Disposition", "attachment;filename=" + UUID.randomUUID().toString() + ".docx");
FileInputStream inputStream = new FileInputStream(path);
int count =0;
byte[] by = new byte[1024];
OutputStream out = response.getOutputStream();
while((count=inputStream.read(by))!=-1){
out.write(by, 0, count);//将缓冲区的数据输出到浏览器
}
inputStream.close();
out.flush();
out.close();
}
}

View File

@ -0,0 +1,66 @@
package com.example.survey.util;
import java.util.HashMap;
import java.util.Map;
import com.example.survey.dao.RecordDao;
import com.example.survey.entity.Record;
import com.example.survey.enumeration.RecordStateEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import lombok.Data;
@Data
@Component
public class ThreadWordUtil implements Runnable {
private Record record;
private Thread t;
private String threadName;
@Value("${file.path}")
private String path;
@Value("${file.report}")
private String report;
@Value("${file.template}")
private String template;
@Autowired
private RecordDao recordDao;
@Override
public void run() {
if(record != null) {
System.out.println("=========Start Export============");
String templatePath = this.template + record.getMetaData().getName() + ".docx";
String outputPath = this.report + record.getUuid() + ".docx";
try{
Map<String, Object> values = record.getValues();
values.put("submit", record.getOperationList().get(0).getUser().getUsername());
values.put("review", record.getOperationList().get(0).getUser().getUsername());
WordUtil wordUtil = new WordUtil(values, templatePath, outputPath);
wordUtil.export2word();
record.setState(RecordStateEnum.REVIEWED.getValue());
recordDao.saveRecord(record);
}
catch(Exception e) {
e.printStackTrace();
}
}
}
public void start() {
t = new Thread(this, threadName);
t.start();
}
}

View File

@ -1,81 +1,216 @@
package com.example.survey.util;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.config.ConfigureBuilder;
import com.deepoove.poi.policy.HackLoopTableRenderPolicy;
import com.example.survey.entity.MetaData;
import com.example.survey.entity.Record;
import org.apache.commons.io.FileUtils;
import org.apache.poi.ooxml.POIXMLDocument;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.Document;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.apache.xmlbeans.XmlCursor;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
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.lang.reflect.Method;
import java.util.*;
import java.util.Map.Entry;
/**
* @author Pope
*/
// @Component
public class WordUtil {
public static void export2word(HttpServletResponse response, Map<String, Object> values, String templatePath) {
response.addHeader("Content-Disposition", "attachment;filename=" + UUID.randomUUID().toString() + ".docx");
private CustomXWPFDocument document;
private HashMap<String, Method> key2methods;
private Map<String, Object> values;
private String outputPath;
private File temp;
ConfigureBuilder configureBuilder = Configure.builder();
HackLoopTableRenderPolicy policy = new HackLoopTableRenderPolicy();
for (String key : values.keySet()) {
Object value = values.get(key);
if (value instanceof List) {
List<Object> newValue = (List<Object>) value;
if(newValue.size()==0){
public WordUtil(Map<String, Object> values, String templatePath, String outputPath)
throws FileNotFoundException, IOException, NoSuchMethodException, SecurityException {
temp = new File(UUID.randomUUID() + "t.docx");
this.outputPath = outputPath;
FileUtils.copyFile(new File(templatePath), temp);
OPCPackage pack = POIXMLDocument.openPackage(temp.getAbsolutePath());
document = new CustomXWPFDocument(pack);
this.values = values;
key2methods = new HashMap<>();
key2methods.put("$", getClass().getDeclaredMethod("processText", XWPFTableCell.class, String.class));
key2methods.put("#", getClass().getDeclaredMethod("processImage", XWPFTableCell.class, String.class));
key2methods.put("@", getClass().getDeclaredMethod("processTable", XWPFTableCell.class, String.class));
}
public void export2word()
throws FileNotFoundException, IOException, NoSuchMethodException, SecurityException {
List<XWPFTable> tables = document.getTables();
HashMap<String, XWPFTableCell> runs = new HashMap<>();
for (XWPFTable table : tables) {
// 遍历表格
List<XWPFTableRow> rows = table.getRows();
for (int i = 0; i < rows.size(); i++) {
XWPFTableRow row = table.getRow(i);
List<XWPFTableCell> cells = row.getTableCells();
for (int j = 0; j < cells.size(); j++) {
XWPFTableCell cell = cells.get(j);
String key = cell.getText();
if (key.length() == 0) {
continue;
}
Object o = newValue.get(0);
if (o instanceof String) {
StringBuilder sb = new StringBuilder();
newValue.forEach(str -> {
sb.append(str + " ");
});
values.put(key, sb.toString());
String keyHead = key.substring(0, 1);
String trueKey = key.substring(1);
if (key2methods.containsKey(keyHead)) {
cell.removeParagraph(0);
} else {
configureBuilder = configureBuilder.bind(key, policy);
continue;
}
if (values.containsKey(trueKey)) {
runs.put(key, cell);
} else {
cell.setText("");
}
}
}
XWPFTemplate template = XWPFTemplate.compile(templatePath, configureBuilder.build()).render(values);
try (BufferedOutputStream os = new BufferedOutputStream(response.getOutputStream())) {
template.write(os);
} catch (IOException e) {
e.printStackTrace();
} finally {
}
for (Entry<String, XWPFTableCell> entry : runs.entrySet()) {
String key = entry.getKey();
XWPFTableCell cell = entry.getValue();
Method method = key2methods.get(key.subSequence(0, 1));
String trueKey = key.substring(1);
try {
template.close();
} catch (IOException e) {
method.invoke(this, cell, values.get(trueKey));
// System.out.println(key + ":" + values.get(key));
} catch (Exception e) {
e.printStackTrace();
cell.setText("");
}
}
}
public static void export2Word(HttpServletResponse response, MetaData metaData, Record record){
Map<String, Object> values = record.getValues();
// String templatePath = metaData.getWordTemplate();
for (Map.Entry<String, Object> entry : metaData.getForm().entrySet()) {
OutputStream outputStream = new FileOutputStream(outputPath);
// document.
document.write(outputStream);
outputStream.close();
document.close();
FileUtils.forceDelete(temp);
}
private void processText(XWPFTableCell cell, String msg) {
// 执行\n换行
if (msg == null) {
cell.setText("");
return;
}
String[] st = msg.split("\n");
for (int p = 0; p < st.length; p++) {
cell.addParagraph();
}
List<XWPFParagraph> pglist = cell.getParagraphs();
for (int pi = 0; pi < pglist.size(); pi++) {
XWPFRun run = pglist.get(pi).createRun();
if(pi >= st.length){
System.out.println("ERROR!!!!!!!!!!!");
continue;
}
run.setText(st[pi]);
}
public static void handleText(){
}
public static void handleDate(){
private void processImage(XWPFTableCell cell, String imgInfo) {
String[] infos = imgInfo.split(":");
String imgPath = infos[0];
int imgHeight = Integer.parseInt(infos[1]);
int imgWidth = Integer.parseInt(infos[2]);
XWPFParagraph paragraph = cell.addParagraph();
int length = paragraph.getRuns().size();
if (length > 0) {
for (int idx = (length - 1); idx >= 0; idx--) {
paragraph.removeRun(idx);
}
}
try {
String blipId = document.addPictureData(new FileInputStream(new File(imgPath)), Document.PICTURE_TYPE_PNG);
document.createPicture(blipId, document.getNextPicNameNumber(Document.PICTURE_TYPE_PNG), imgHeight,
imgWidth, paragraph);
} catch (Exception e) {
try {
cell.removeParagraph(0);
processText(cell, infos[3]);
} catch (Exception e1) {
cell.setText("");
e1.printStackTrace();
}
// e.printStackTrace();
}
}
private void processTable(XWPFTableCell cell, String tableInfos) {
String[] infos = tableInfos.split("&");
String tableMetaInfo = infos[0];
String tableContent = infos[1];
String[] mInfos = tableMetaInfo.split(":");
int rows = Integer.parseInt(mInfos[0]);
int cols = Integer.parseInt(mInfos[1]);
XmlCursor cursor = cell.addParagraph().getCTP().newCursor();
// cursor
XWPFTable table = cell.insertNewTbl(cursor);
String[] rowsString = tableContent.split("\r\n");
for (int i = 0; i < rows; i++) {
if (rowsString.length <= i) {
break;
}
XWPFTableRow row = table.createRow();
if (i == 0) {
for (int j = 0; j < cols; j++) {
row.addNewTableCell();
}
}
String[] colsString = rowsString[i].split("\t");
for (int j = 0; j < cols; j++) {
if (colsString.length <= j) {
break;
}
String msg = colsString[j];
XWPFTableCell tableCell = row.getCell(j);
tableCell.removeParagraph(0);
try {
processText(tableCell, msg);
} catch (Exception e) {
tableCell.setText("");
}
}
}
}
public static void handleList(){
public static String generateImageStr(String path, int w, int h, String alt) {
return path + ":" + String.valueOf(w) + ":" + String.valueOf(h) + ":" + alt;
}
}

View File

@ -0,0 +1,30 @@
package com.example.survey.vo;
import com.example.survey.vo.inner.OperationInfo;
import lombok.Data;
import java.util.List;
import java.util.Map;
/**
* @author Pope
*/
@Data
public class RecordDetailVO {
private String idNumber;
private List<String> projectList;
private String template;
private String uuid;
private long submitTime;
private List<OperationInfo> operationInfoList;
private Map<String, Object> values;
private String state;
}

View File

@ -14,7 +14,7 @@ public class RecordVO {
private String idNumber;
// private List<String> projectList;
private List<String> projectList;
private String template;

View File

@ -19,7 +19,7 @@ public class OperationInfo {
/**
* 时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date time;
/**

View File

@ -18,3 +18,5 @@ spring:
file:
path: ./upload/
url: /upload/
report: ./report/
template: ./template/

View File

@ -1,7 +1,6 @@
spring:
data:
mongodb:
# uri: mongodb://cveo:cveo123456@120.78.177.67:27017/survey
#创建索引
auto-index-creation: true
host: mongo
@ -19,7 +18,8 @@ spring:
file:
path: ./data/upload/
url: /upload/
report: ./data/report/
template: ./data/template/
# kafka:
# bootstrap-servers: localhost:9092 # 指定kafka 代理地址,可以多个
# producer: # 生产者

View File

@ -1,3 +1,3 @@
spring:
profiles:
active: dev
active: prod