使用xdocreport 生成word
网页导出word文档,需要生成表格,表格内有些内容是一行两列的,左侧列是标题,右侧列是数据,现在对数据列进行加域处理,使用的是«@before-row[#list studentXXZT as l]»« ${l.XXZT}» «@after-row[/#list]»进行遍历,数据列有多条数据的话,会在原有模板基础下,在当前行向下生成新的数据行,一条数据占一行。
期望达成的效果如图:
目前效果:
#问题描述:
数据行会生成,但是左侧标题列也会跟着生成新的行,并且内容自动填充。
注:后端代码是没问题的数据能正常封装。
代码:
public void downLoadWord(String id) throws IOException {
String getXC = "select XCC_YEAR,XCC_XXCS,XCC_XXRQ,XCC_XXSC,XCC_XXDD,XCC_CYCQL,XCC_WCJRYJYY,XCC_XCZP,XCC_TBRLXR,XCC_LXRY from SASIRMPROPAGANDA where id = '" + id + "'";
Map<String, Object> XCMap = NativeQueryUtils.queryOne(getXC);
String imageSql = "select * from eisimagefile where billid = '" + id + "'";
List<Map<String, Object>> imageMapList = NativeQueryUtils.queryList(imageSql);
try {
Properties allproper = PropertiesUtil.getAllproper();
// String confFile = allproper.getProperty("wordPath");
String confFile = "server" + File.separator + "runtime" + File.separator + "recordTable.docx";
File conf = new File(confFile);
if (!conf.exists()) {
log.error(conf.getAbsolutePath() + "配置文件不存在");
}
InputStream ins = new FileInputStream(conf);
//注册xdocreport实例并加载FreeMarker模板引擎
IXDocReport report = XDocReportRegistry.getRegistry().loadReport(ins, TemplateEngineKind.Freemarker);
//创建xdocreport上下文对象
IContext context = report.createContext();
//创建字段元数据
FieldsMetadata fm = report.createFieldsMetadata();
List<TestPicNameVo> list = new ArrayList<>();
List<TestPicVo> picVoList = new ArrayList<>();
TestPicNameVo picNameVo1 = new TestPicNameVo();
//List<IImageProvider> imagList = new ArrayList<>(); //---
//验证是否能导出图片
/*IImageProvider p1 = new FileImageProvider(new File("E:\\images\\woman\\1.jpg"));
TestPicVo testPicVo1 = new TestPicVo(p1);
TestPicNameVo picNameVo1 = new TestPicNameVo();
picVoList.add(testPicVo1);
IImageProvider p2 = new FileImageProvider(new File("E:\\images\\woman\\2.jpg"));
TestPicVo testPicVo2 = new TestPicVo(p2);
picVoList.add(testPicVo2);
picNameVo1.setPicVoList(picVoList);
list.add(picNameVo1);*/
for (Map<String, Object> imageMap : imageMapList) {
String ext = String.valueOf(imageMap.get("ext"));
if (verifyIfPicture(ext)) {
String FileID = String.valueOf(imageMap.get("id"));
LinkedHashMap<String, Object> map = new LinkedHashMap();
HashMap<Object, Object> paramMap = new HashMap<>();
paramMap.put("FileID", FileID);
map.put("imageFileMapParam", paramMap);
ResultFrontModel result = this.client.invoke(ResultFrontModel.class, "com.inspur.gs.eis.image.restful.eis.ImageAPIEisRest.getImageFileByFileID", "EIS", map, null);
String code = result.code;
String imageFileBytes = ((LinkedHashMap) result.data).get("imageFileBytes").toString();
byte[] decode = Base64.getDecoder().decode(imageFileBytes);
InputStream inputStream = new ByteArrayInputStream(decode);
//测试图片是否完整
/*File filess = File.createTempFile("abc",".jpg");
try (OutputStream outputStream = new FileOutputStream(filess)) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
}*/
File file = inputStreamToFile(inputStream);
FileImageProvider fileImageProvider = new FileImageProvider(file);
//imagList.add(fileImageProvider); //---
TestPicVo testPicVo = new TestPicVo(fileImageProvider);
picVoList.add(testPicVo);
}
picNameVo1.setPicVoList(picVoList);
}
list.add(picNameVo1);
context.put("data", list);
fm.load("data", TestPicNameVo.class, true);
//fm.addFieldAsImage("pic","pic", NullImageBehaviour.RemoveImageTemplate);
fm.addFieldAsImage("pic","list1.pic", NullImageBehaviour.RemoveImageTemplate);
//创建要替换的文本变量
context.put("XCC_YEAR", String.valueOf(XCMap.get("xcc_year")));
context.put("XCC_XXCS", String.valueOf(XCMap.get("xcc_xxcs")));
context.put("XCC_XXRQ", String.valueOf(XCMap.get("xcc_xxrq")));
context.put("XCC_XXSC", String.valueOf(XCMap.get("xcc_xxsc")));
context.put("XCC_XXDD", String.valueOf(XCMap.get("xcc_xxdd")));
context.put("XCC_CYCQL", String.valueOf(XCMap.get("xcc_cycql")));
context.put("XCC_WCJRYJYY", String.valueOf(XCMap.get("xcc_wcjryjyy")));
context.put("XCC_XCZP", String.valueOf(XCMap.get("xcc_xczp")));
context.put("XCC_TBRLXR", String.valueOf(XCMap.get("xcc_tbrlxr")));
context.put("XCC_LXRY", String.valueOf(XCMap.get("xcc_lxry")));
context.put("XXZT", "学习专题");
context.put("XXYC", "学习议程");
//学习专题子表
String getXXzt = "select * from SASIRMPROPAGANDAXXZT where PARENTID = '" + id + "'";
List<Map<String, Object>> mapList = NativeQueryUtils.queryList(getXXzt);
if (mapList.size() > 0) {
List<LearningTopicsDto> propagandaxxzt = new ArrayList<>();
for (int i = 0; i < mapList.size(); i++) {
LearningTopicsDto learningTopicsDto = new LearningTopicsDto();
String xxzt = ObjectUtils.isEmpty(mapList.get(i).get("xxzt").toString()) ? "" : mapList.get(i).get("xxzt").toString();
learningTopicsDto.setXXZT(xxzt);
propagandaxxzt.add(learningTopicsDto);
}
context.put("studentXXZT", propagandaxxzt);
fm.load("studentXXZT", LearningTopicsDto.class, true);
}
//学习议程子表
String getXXyc = "select * from SASIRMPROPAGANDAXXYC where PARENTID = '"+id+"'";
List<Map<String, Object>> YcMapList = NativeQueryUtils.queryList(getXXyc);
if(YcMapList.size()>0){
ArrayList<LearningAgendaDto> propagandaxxyc = new ArrayList<>();
for (int i = 0; i < YcMapList.size(); i++) {
LearningAgendaDto learningAgendaDto = new LearningAgendaDto();
String xxyc = ObjectUtils.isEmpty(YcMapList.get(i).get("xxyc").toString()) ? "" : YcMapList.get(i).get("xxyc").toString();
learningAgendaDto.setXXYC(xxyc);
propagandaxxyc.add(learningAgendaDto);
}
context.put("studentXXYC",propagandaxxyc);
fm.load("studentXXYC",LearningAgendaDto.class,true);
}
//发言题目子表
String getFYtm = "select * from SASIRMPROPAGANDAFYTM where PARENTID = '"+id+"'";
List<Map<String, Object>> FyMapList = NativeQueryUtils.queryList(getFYtm);
if(FyMapList.size() > 0){
ArrayList<SpeechTitleDto> propagandafytm = new ArrayList<>();
for (int i = 0; i < FyMapList.size(); i++) {
SpeechTitleDto speechTitleDto = new SpeechTitleDto();
String workZDFYMC = ObjectUtils.isEmpty(FyMapList.get(i).get("zdfymc").toString()) ? "" : FyMapList.get(i).get("zdfymc").toString();
String workFYTM = ObjectUtils.isEmpty(FyMapList.get(i).get("fytm").toString()) ? "" : FyMapList.get(i).get("fytm").toString();
speechTitleDto.setZDFYMC(workZDFYMC);
speechTitleDto.setFYTM(workFYTM);
propagandafytm.add(speechTitleDto);
}
context.put("studentFYTM",propagandafytm);
fm.load("studentFYTM",SpeechTitleDto.class,true);
}
//输出到本地目录
//FileOutputStream out = new FileOutputStream(new File("D://商品销售报表.docx"));
//report.process(context, out);
//浏览器端下载
RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
RequestContextHolder.getRequestAttributes();
HttpServletResponse response = ((ServletRequestAttributes)requestAttributes).getResponse();
assert response != null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
response.setCharacterEncoding("utf-8");
response.setContentType("application/msword;charset=utf-8");
// response.setHeader("Content-Length", String.valueOf(bais.available()));
response.addHeader("Content-Disposition", "attachment;filename= 记录表.docx");
String fileName = "记录表.docx";
response.setHeader("Content-Disposition", "attachment;filename="
.concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8"))));
// report.setFieldsMetadata(fm);
report.process(context, response.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
还有个问题是导出多个图片,然后导出来的文件,用wps打开没问题,用word2019打开报无法读取内容,需要恢复,点击恢复后也能打开,然后用word2016打开得时候就直接报无法打开,报文件错误,求解答