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

4
.gitignore vendored
View File

@ -48,4 +48,6 @@ gen
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
/upload/**
/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,9 +36,11 @@ 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");
add("/user/user : DELETE");
@ -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);
project.setCount(project.getCount() + 1);
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);
project.setCount(project.getCount() - 1);
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) {
@ -58,13 +67,14 @@ public class RecordServiceImpl implements RecordService {
throw new UserException(ResultEnum.NOT_EXIST_USER);
}
User user = userDao.selectUser(reviewRecordDTO.getReviewerPhone());
if (!recordDao.existRecord(reviewRecordDTO.getUuid())) {
throw new RecordException(ResultEnum.NOT_EXIST_RECORD);
}
Record record = recordDao.getRecord( reviewRecordDTO.getUuid());
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();
@ -80,7 +90,7 @@ public class RecordServiceImpl implements RecordService {
throw new UserException(ResultEnum.NOT_EXIST_USER);
}
User user = userDao.selectUser(modifyRecordDTO.getUserPhone());
Record record = recordDao.getRecord(modifyRecordDTO.getUuid());
if (record == null) {
throw new RecordException(ResultEnum.NOT_EXIST_RECORD);
@ -106,7 +116,7 @@ public class RecordServiceImpl implements RecordService {
}
MetaData metaData = metaDataDao.selectMetaData(submitRecordDTO.getMetaDataName());
Record record = new Record();
record.setUser(user);
record.setValues(submitRecordDTO.getValues());
Operation submitOp = Operation.submitOp(user, submitRecordDTO.getMsg());
@ -123,24 +133,30 @@ public class RecordServiceImpl implements RecordService {
}
@Override
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);
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);
}
@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) {
List<Record> recordList = recordDao.listRecordLimit(idNumber, state, uuid, templateName, templateType, submitTimeGt, submitTimeLt, projectName, currentPage * pageSize, 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);
return recordList.stream().map(record -> {
RecordVO recordVO = new RecordVO();
recordVO.setIdNumber(record.getIdNumber());
recordVO.setUuid(record.getUuid());
recordVO.setTemplate(record.getMetaData().getName());
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
@ -210,7 +250,7 @@ public class RecordServiceImpl implements RecordService {
throw new UserException(ResultEnum.NOT_EXIST_USER);
}
User user = userDao.selectUser(deleteRecordDTO.getPhone());
Record record = recordDao.getRecord(deleteRecordDTO.getUuid());
if (record == null) {
throw new RecordException(ResultEnum.NOT_EXIST_RECORD);
@ -224,21 +264,35 @@ 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
public void modifyMetaData(ModifyMetaDataDTO modifyMetaDataDTO) {
if (!metaDataDao.existMetaData(modifyMetaDataDTO.getMetaDataName())) {
throw new MetaDataException(ResultEnum.NOT_EXIST_METADATA);
}
MetaData metaData = metaDataDao.selectMetaData(modifyMetaDataDTO.getMetaDataName());
Record record = recordDao.getRecord(modifyMetaDataDTO.getUuid());
if(record == null) {
if (record == null) {
throw new RecordException(ResultEnum.NOT_EXIST_RECORD);
}
@ -248,7 +302,7 @@ public class RecordServiceImpl implements RecordService {
User user = userDao.selectUser(modifyMetaDataDTO.getPhone());
List<Operation> operationList = record.getOperationList();
String msg = record.getMetaData().getName() +"->" + modifyMetaDataDTO.getMetaDataName();
String msg = record.getMetaData().getName() + "->" + modifyMetaDataDTO.getMetaDataName();
Operation modifyMetaOp = Operation.modifyMetaOp(user, msg);
// modifyMetaOp.setMsg();
operationList.add(modifyMetaOp);
@ -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){
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());
} else {
configureBuilder = configureBuilder.bind(key, policy);
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;
}
String keyHead = key.substring(0, 1);
String trueKey = key.substring(1);
if (key2methods.containsKey(keyHead)) {
cell.removeParagraph(0);
} else {
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("");
}
}
OutputStream outputStream = new FileOutputStream(outputPath);
// document.
document.write(outputStream);
outputStream.close();
document.close();
FileUtils.forceDelete(temp);
}
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()) {
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]);
}
}
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 handleText(){
public static String generateImageStr(String path, int w, int h, String alt) {
return path + ":" + String.valueOf(w) + ":" + String.valueOf(h) + ":" + alt;
}
public static void handleDate(){
}
public static void handleList(){
}
}

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