赞
踩
根据模板生成WORD文件,模板文件参数可配.
先看一下导出的demo文件,具体参数可手动修改
下图为word_demo.docx导出的WORD文件
下图为word_list.docx导出的WORD文件
WORD文件模板,新建WORD文件,将所需参数用特殊符号 ${} 配置,如下图.
demo模板(数据替换模板中的配置参数) : word_demo.docx
demo模板(导出数据列表,数据表格在文件下方自动拼接) : word_list.docx
项目采用springboot框架
<!--WORD导出POM-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.8</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>3.8</version>
</dependency>
WORD导出接口类 WordController.java
package com.chang.word; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import java.util.ArrayList; import java.util.List; /** * WORD导出 * @author message丶小和尚 * @create 2020/01/10 */ @Controller public class WordController { @Resource private WordExportService wordExportService;//Word导出工具 @RequestMapping("exportWordDemo") @ResponseBody public void exportWordDemo(HttpServletResponse response, @RequestParam("param")String param) throws Exception{ WordResult wordResult = new WordResult(); wordResult.setData(param); wordExportService.toWordDemo(response, wordResult); } @RequestMapping("exportWordList") @ResponseBody public void exportWordList(HttpServletResponse response, @RequestParam("param")String param) throws Exception{ List<WordResult> wordResultList = new ArrayList<>(); WordResult wordResult = new WordResult(); wordResult.setData(param); wordResultList.add(wordResult); wordExportService.toWordList(response, wordResult, wordResultList); } }
WORD导出工具类 WordExportService.java
package com.chang.word; import org.springframework.stereotype.Service; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.OutputStream; import java.util.List; /** * 模板文档下载 * @author message丶小和尚 * @create 2020/01/10 */ @Service public class WordExportService { //文件名 private final static String DEMO_WORD_FILE="模板demo文件"; private final static String DEMO_WORD_LIST="模板list文件"; public void toWordDemo(HttpServletResponse response, WordResult wordResult)throws Exception{ byte[] bytes = WordBaseService.toWordDemo(wordResult); if(bytes != null){ uploadWord(response,bytes,DEMO_WORD_FILE); } } public void toWordList(HttpServletResponse response, WordResult wordResult, List<WordResult> publicResultList)throws Exception{ byte[] bytes = WordBaseService.toWordList(wordResult,publicResultList); if(bytes != null){ uploadWord(response,bytes,DEMO_WORD_LIST); } } /** * 下载模板 * @param response 响应 * @param bytes 字节 * @param fileName 文件名 * @throws Exception */ private void uploadWord(HttpServletResponse response, byte[] bytes, String fileName) throws Exception{ try { if(bytes != null){ // OutputStream outputStream = new FileOutputStream("E:ceshi.docx"); OutputStream outputStream = response.getOutputStream(); response.setCharacterEncoding("utf-8"); response.setContentType("application/x-download"); HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); String userAgent = request.getHeader("User-Agent"); byte[] byteName = userAgent.contains("MSIE") ? fileName.getBytes() : fileName.getBytes("UTF-8");//name.getBytes("UTF-8")处理safari的乱码问题 fileName = new String(byteName, "ISO-8859-1"); // 各浏览器基本都支持ISO编码 response.setHeader("Content-disposition", String.format("attachment; filename=\"%s\"", fileName+".docx"));//文件名外的双引号处理firefox的空格截断问题 InputStream is = new ByteArrayInputStream(bytes); byte[] buff = new byte[1024]; int len = 0; while ((len = is.read(buff)) != -1) { outputStream.write(buff, 0, len); } is.close(); outputStream.close(); } } catch (Exception e) { throw(e); } } }
WORD导出工具类 WordBaseService.java
package com.chang.word; import lombok.extern.slf4j.Slf4j; import org.apache.poi.xwpf.usermodel.ParagraphAlignment; import org.apache.poi.xwpf.usermodel.XWPFDocument; 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.XWPFTableRow; import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc; import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalJc; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import java.io.ByteArrayOutputStream; import java.io.File; import java.math.BigInteger; import java.util.List; import java.util.Map; /** * @author message丶小和尚 * @create 2020/01/10 * 模板下载 */ @Slf4j @Component public class WordBaseService { private static String templateBasePath = "/app/static/template/"; private final static String WORD_DEMO = "word_demo.docx"; private final static String WORD_LIST = "word_list.docx"; //Word导出,参数配置 public static byte[] toWordDemo(WordResult wordResult) throws Exception { return toWordObjectMap(wordResult,WORD_DEMO); } private static byte[] toWordObjectMap(Object obj,String filePath) throws Exception{ byte[] bytes = null; if(obj != null ){ bytes = toWordAllModelAnalysis(WordUtil.setMapObject(obj),templateBasePath + filePath); } return bytes; } private static byte[] toWordAllModelAnalysis(Map<String, Object> mapObject, String modelPath) throws Exception { byte[] bytes = null; if(mapObject != null && !StringUtils.isEmpty(modelPath)){ File file = new File(modelPath); if(!file.exists()&&!file.isFile()){ log.error("模板文件不存在"); return null; } try { XWPFDocument doc = WordUtil.generateWord(mapObject, modelPath); ByteArrayOutputStream baos=new ByteArrayOutputStream(); doc.write(baos); bytes = baos.toByteArray(); baos.close(); } catch (Exception e) { log.error("文件处理异常",e); } } return bytes; } //Word导出,列表设置 public static byte[] toWordList(WordResult wordResult, List<WordResult> publicResultList) throws Exception { return toWordObjectMapPublic(wordResult,publicResultList,WORD_LIST); } private static byte[] toWordObjectMapPublic(Object obj, List<WordResult> list, String filePath) throws Exception{ byte[] bytes = null; if(obj != null ){ bytes = toWordAllModelAnalysisPublic(WordUtil.setMapObject(obj),list,templateBasePath+filePath); } return bytes; } private static byte[] toWordAllModelAnalysisPublic(Map<String, Object> mapObject,List<WordResult> list, String modelPath) throws Exception { byte[] bytes = null; if(mapObject != null && !StringUtils.isEmpty(modelPath)){ File file = new File(modelPath); if(!file.exists()&&!file.isFile()){ log.error("模板文件不存在"); return null; } try { XWPFDocument doc = WordUtil.generateWord(mapObject, modelPath); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); //插入表格 XWPFTable table = doc.createTable(); table.getCTTbl().addNewTblPr().addNewJc().setVal(STJc.CENTER);//设置表格居中 //设置表头 XWPFTableRow tableRowOne = table.getRow(0); XWPFParagraph paragraph0 = getStyle(doc.createParagraph(),"序号"); tableRowOne.getCell(0).setParagraph(paragraph0); paragraph0.removeRun(0); tableRowOne.getCell(0).getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(1000));//设置宽度 tableRowOne.getCell(0).getCTTc().addNewTcPr().addNewVAlign().setVal(STVerticalJc.CENTER);//设置水平居中 // tableRowOne.getCell(0).getCTTc().getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER); XWPFParagraph paragraph1 = getStyle(doc.createParagraph(),"数据"); tableRowOne.addNewTableCell().setParagraph(paragraph1); paragraph1.removeRun(0); tableRowOne.getCell(1).getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(1500));//设置宽度 tableRowOne.getCell(1).getCTTc().addNewTcPr().addNewVAlign().setVal(STVerticalJc.CENTER);//设置水平居中 // tableRowOne.getCell(1).getCTTc().getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER); //循环设置Word表格内容 for (int i = 0; i < list.size(); i++) { XWPFTableRow tableRow = table.createRow(); XWPFParagraph paragraph00 = getStyleNotBold(doc.createParagraph(),String.valueOf(i+1)); tableRow.getCell(0).setParagraph(paragraph00); paragraph00.removeRun(0); XWPFParagraph paragraph01 = getStyleNotBold(doc.createParagraph(),list.get(i).getData()); tableRow.getCell(1).setParagraph(paragraph01); paragraph01.removeRun(0); tableRow.getCell(0).getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(1000)); tableRow.getCell(0).getCTTc().addNewTcPr().addNewVAlign().setVal(STVerticalJc.CENTER);//设置水平居中 // tableRow.getCell(0).getCTTc().getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER); tableRow.getCell(1).getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(1500)); tableRow.getCell(1).getCTTc().addNewTcPr().addNewVAlign().setVal(STVerticalJc.CENTER);//设置水平居中 // tableRow.getCell(1).getCTTc().getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER); } doc.write(byteArrayOutputStream); bytes = byteArrayOutputStream.toByteArray(); byteArrayOutputStream.close(); } catch (Exception e) { log.error("文件处理异常",e); } } return bytes; } //设置段落格式 private static XWPFParagraph getStyle(XWPFParagraph paragraphX, String name){ paragraphX.setAlignment(ParagraphAlignment.CENTER);//对齐方式 XWPFRun runXOne = paragraphX.createRun();//创建文本对象 runXOne.setText(name); runXOne.setFontSize(15);//字体大小 runXOne.setFontFamily("黑体");//字体 runXOne.setBold(true);//加粗 runXOne.setTextPosition(10);//设置行间距 return paragraphX; } //设置段落格式 private static XWPFParagraph getStyleNotBold(XWPFParagraph paragraphX, String name){ paragraphX.setAlignment(ParagraphAlignment.CENTER);//对齐方式 XWPFRun runXOne = paragraphX.createRun();//创建文本对象 runXOne.setText(name); runXOne.setFontSize(14);//字体大小 runXOne.setBold(false);//加粗 runXOne.setTextPosition(10);//设置行间距 return paragraphX; } }
WORD导出工具类 WordUtil.java
package com.chang.word; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.poi.POIXMLDocument; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.xwpf.usermodel.XWPFDocument; 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.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 java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; /** * @author message丶小和尚 * @create 2020/01/10 * 模板的装载过程 */ public class WordUtil { private static Log log = LogFactory.getLog(WordUtil.class); /** * 装载模板所对应的对象 * @param object * @return map */ public static Map<String,Object> setMapObject(Object object){ Map<String,Object> mapObject = new HashMap<String,Object>(); if(object != null){ Field[] fields = object.getClass().getDeclaredFields(); log.info("fields" + fields.length); for(Field field : fields){ try { field.setAccessible(true); String str = "${" + field.getName() + "}"; Object objValue = field.get(object); if(objValue != null){ log.info(str + "----" + objValue.toString()); mapObject.put(str, objValue); }else{ mapObject.put(str, ""); } } catch(Exception e) { log.error("模板对象出现错误", e); } } } else { log.error("模板对象不是对应的一个类对象"); } return mapObject; } /** * 根据指定的参数值、模板,生成 word 文档 * @param param 需要替换的变量 * @param template 模板 * @return XWPFDocument * @throws IOException * @throws InvalidFormatException */ public static XWPFDocument generateWord(Map<String, Object> param, String template) throws IOException, InvalidFormatException { if(param == null || template == null){ return null ; } XWPFDocument xwpfDocument = null; log.info("解析的模版为:" + template); try { OPCPackage pack = POIXMLDocument.openPackage(template); xwpfDocument = new XWPFDocument(pack); if (param.size() > 0) { //处理段落 List<XWPFParagraph> paragraphList = xwpfDocument.getParagraphs(); processParagraphs(paragraphList, param, xwpfDocument); //处理表格 Iterator<XWPFTable> it = xwpfDocument.getTablesIterator(); while (it.hasNext()) { XWPFTable table = it.next(); List<XWPFTableRow> rows = table.getRows(); for (XWPFTableRow row : rows) { List<XWPFTableCell> cells = row.getTableCells(); for (XWPFTableCell cell : cells) { List<XWPFParagraph> paragraphListTable = cell.getParagraphs(); processParagraphs(paragraphListTable, param, xwpfDocument); } } } } } catch (IOException e) { log.error("文件处理异常", e); throw(e); }catch (InvalidFormatException e) { log.error("文档中内容处理异常", e); throw(e); } return xwpfDocument; } /** * 处理段落 * @param paragraphList * @param param * @param doc * @throws InvalidFormatException * @throws FileNotFoundException */ public static void processParagraphs(List<XWPFParagraph> paragraphList, Map<String, Object> param, XWPFDocument doc) throws InvalidFormatException, FileNotFoundException{ if(paragraphList != null && paragraphList.size() > 0){ for(XWPFParagraph paragraph : paragraphList){ List<XWPFRun> runs = paragraph.getRuns(); for (XWPFRun run : runs) { String text = run.getText(0); if(text != null){ boolean isSetText = false; for (Map.Entry<String, Object> entry : param.entrySet()) { String key = entry.getKey(); if(text.indexOf(key) != -1){ isSetText = true; Object value = entry.getValue(); if (value instanceof String) {//文本替换 log.info(key + "模板中模要转化属性对应的值:" + value); text = text.replace(key, value.toString()); } else if (value instanceof Map) {//图片替换 text = text.replace(key, ""); Map pic = (Map)value; int width = Integer.parseInt(pic.get("width").toString()); int height = Integer.parseInt(pic.get("height").toString()); int picType = getPictureType(pic.get("type").toString()); String byteArray = (String) pic.get("imgPath"); log.info("模板中模要转化的图片" + byteArray); CTInline inline = run.getCTR().addNewDrawing().addNewInline(); insertPicture(doc,byteArray,inline, width, height); } } } if(isSetText){ run.setText(text,0); } } } } } } /** * 根据图片类型,取得对应的图片类型代码 * @param picType * @return int */ private static int getPictureType(String picType){ int res = XWPFDocument.PICTURE_TYPE_PICT; if(picType != null){ if(picType.equalsIgnoreCase("png")){ res = XWPFDocument.PICTURE_TYPE_PNG; }else if(picType.equalsIgnoreCase("dib")){ res = XWPFDocument.PICTURE_TYPE_DIB; }else if(picType.equalsIgnoreCase("emf")){ res = XWPFDocument.PICTURE_TYPE_EMF; }else if(picType.equalsIgnoreCase("jpg") || picType.equalsIgnoreCase("jpeg")){ res = XWPFDocument.PICTURE_TYPE_JPEG; }else if(picType.equalsIgnoreCase("wmf")){ res = XWPFDocument.PICTURE_TYPE_WMF; } } return res; } /** * 将输入流中的数据写入字节数组 * @param inputStream * @param isClose * @return */ public static byte[] inputStream2ByteArray(InputStream inputStream,boolean isClose){ byte[] byteArray = null; try { int total = inputStream.available(); byteArray = new byte[total]; inputStream.read(byteArray); } catch (IOException e) { log.error("IO异常",e); } finally { if(isClose){ try { inputStream.close(); } catch (Exception e2) { log.debug("关闭流失败"); } } } return byteArray; } /** * * @param document * @param filePath * @param inline * @param width * @param height * @throws InvalidFormatException * @throws FileNotFoundException */ private static void insertPicture(XWPFDocument document, String filePath, CTInline inline, int width, int height) throws InvalidFormatException, FileNotFoundException { document.addPictureData(new FileInputStream(filePath), XWPFDocument.PICTURE_TYPE_PNG); int id = document.getAllPictures().size() - 1; final int EMU = 9525; width *= EMU; height *= EMU; // String blipId = document.getAllPictures().get(id).getPackageRelationship().getId(); Integer blipIdString = document.getAllPictures().get(id).getPictureType(); String blipId = blipIdString.toString(); String picXml = getPicXml(blipId, width, height); XmlToken xmlToken = null; try { xmlToken = XmlToken.Factory.parse(picXml); } catch (XmlException xe) { log.error("XmlException",xe); } inline.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("IMG_" + id); docPr.setDescr("IMG_" + id); } /** * get the xml of the picture * @param blipId * @param width * @param height * @return */ private static String getPicXml(String blipId, int width, int height) { 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=\"" + 0 + "\" 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>"; return picXml; } }
WORD导出实体类(模板所需参数) WordResult.java
package com.chang.word; import java.io.Serializable; /** * WORD导出参数类 * @author message丶小和尚 * @create 2020/01/10 */ public class WordResult implements Serializable { private static final long serialVersionUID = 1L; public String data; public String getData() { return data; } public void setData(String data) { this.data = data; } }
在WordExportService中,可设置导出的Word文件名.
在WordBaseService中,可设置Word模板配置的地址,以及配置模板名称
在真实的业务场景中,可能会涉及Word中表格的导出。表格并不是拼接在文档末尾,而是设置在文档中,即某个段落与段落之间,类似下图这种情况。
对于这种在固定位置插入表格的情况,我们可采用同样的占位符的方式来实现。
如图所示,定义一个占位符 ${make_newTable},当然里面的内容可以自己定义,需注意不能与文档中其他占位符同名即可。
前提是前面的架子已经搭好。
这里的实现结果为标准表格导出,如果需要特殊表格,即合并单元格等,可改造该方法,对cell做特殊处理即可。
在WordTempleCommonService.java文件中增加方法如下:
//通用导出WORD 包含list public static byte[] toWordCommonIndexList(Object obj,List<String> head,List<List<String>> list,String filePath) throws Exception{ byte[] bytes = null; if(obj != null ){ bytes = toWordAllModelAnalysisCommonIndexList(WordUtil.setMapObject(obj),head,list,WordConstant.TEMPLATE_BASE_PATH + filePath); } return bytes; } private static byte[] toWordAllModelAnalysisCommonIndexList(Map<String, Object> mapObject,List<String> head,List<List<String>> stringList, String modelPath) throws Exception { byte[] bytes = null; if(mapObject != null && !StringUtils.isEmpty(modelPath)){ File file = new File(modelPath); if(!file.exists() && !file.isFile()){ return null; } try { XWPFDocument doc = WordUtil.generateWord(mapObject, modelPath); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); List<XWPFParagraph> xwpfParagraphList = doc.getParagraphs(); for(int s = 0; s < xwpfParagraphList.size(); s++){ XWPFParagraph xwpfParagraphIndex = xwpfParagraphList.get(s); if("${make_newTable}".equals(xwpfParagraphIndex.getText())){ XmlCursor cursor = xwpfParagraphIndex.getCTP().newCursor(); XWPFTable table = doc.insertNewTbl(cursor); //插入表格 table.getCTTbl().addNewTblPr().addNewJc().setVal(STJc.CENTER);//设置表格居中 //定义map Map<Integer,Integer> map = new HashMap<Integer,Integer>(); //设置表头 XWPFTableRow tableRowOne = table.getRow(0); for(String string:head){ Integer index = head.indexOf(string);//当前所处序号 Integer width = string.length() * 350 + 200; if(0 == index && "序号".equals(string)){ width = 800; } map.put(index,width); XWPFParagraph paragraph = getCommonIndexStyle(doc.createParagraph(), string, true); if(0 == index){ tableRowOne.getCell(0).setParagraph(paragraph); paragraph.removeRun(0); tableRowOne.getCell(index).getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(width));//设置宽度 tableRowOne.getCell(0).getCTTc().addNewTcPr().addNewVAlign().setVal(STVerticalJc.CENTER);//设置水平居中 tableRowOne.getCtRow().addNewTrPr().addNewTrHeight().setVal(BigInteger.valueOf(600)); } else { tableRowOne.addNewTableCell().setParagraph(paragraph); paragraph.removeRun(0); tableRowOne.getCell(index).getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(width));//设置宽度 tableRowOne.getCell(index).getCTTc().addNewTcPr().addNewVAlign().setVal(STVerticalJc.CENTER);//设置水平居中 tableRowOne.getCtRow().addNewTrPr().addNewTrHeight().setVal(BigInteger.valueOf(600)); } doc.removeBodyElement(doc.getPosOfParagraph(paragraph)); } //循环设置Word表格内容 for(List<String> list : stringList){ XWPFTableRow tableRow = table.createRow(); for(int i = 0; i < list.size(); i++){ CTTcPr tcpr = tableRow.getCell(i).getCTTc().addNewTcPr(); XWPFParagraph paragraph = getCommonIndexStyle(doc.createParagraph(), list.get(i), false); tableRow.getCell(i).setParagraph(paragraph); paragraph.removeRun(0); tcpr.addNewTcW().setW(BigInteger.valueOf(map.get(i)));//设置宽度,表头设置了宽度,此处设置表头的宽度 tcpr.addNewVAlign().setVal(STVerticalJc.CENTER);//设置水平居中 tableRow.getCtRow().addNewTrPr().addNewTrHeight().setVal(BigInteger.valueOf(500)); doc.removeBodyElement(doc.getPosOfParagraph(paragraph)); } } doc.removeBodyElement(doc.getPosOfParagraph(xwpfParagraphIndex)); } } doc.write(byteArrayOutputStream); bytes = byteArrayOutputStream.toByteArray(); byteArrayOutputStream.close(); } catch (Exception e) { log.error("文件处理异常,Exception:", e); } } return bytes; } //设置通用段落格式 private static XWPFParagraph getCommonIndexStyle(XWPFParagraph paragraphX, String name, boolean flag){ paragraphX.setAlignment(ParagraphAlignment.CENTER);//对齐方式 paragraphX.setVerticalAlignment(TextAlignment.CENTER);//对齐方式 XWPFRun runXOne = paragraphX.createRun();//创建文本对象 runXOne.setText(name); if(null == name){ runXOne.setText(""); } runXOne.setFontSize(12);//字体大小 runXOne.setFontFamily("Calibri (正文)");//字体 if(flag){ runXOne.setBold(true);//加粗 } runXOne.setTextPosition(10);//设置行间距 return paragraphX; }
上述代码中需要注意的是:doc.removeBodyElement(doc.getPosOfParagraph(xwpfParagraphIndex));
这是由于我们在生成表格的时候,会去调用 doc.createParagraph(),创建段落,如果不去remove的话,会导致文档产生非常多的空白页。
方法getCommonIndexStyle,其主要作用即设置样式,如果想设置不同样式,可以自行设置即可。
然后在WordTempleService.java文件中增加方法如下:
//指定位置插入表格 ${make_newTable}
public void toWordCommonIndexList(HttpServletResponse response, Object object,List<String> head,List<List<String>> list,String wordTemplate,String fileName)throws Exception{
byte[] bytes = WordTempleCommonService.toWordCommonIndexList(object,head,list,wordTemplate);
if(bytes != null){
uploadWord(response,bytes,fileName);
}
}
上述代码的 uploadWord方法,可在文中找到。
至此方法已经搭建完成,下面是模拟调用。
wordTempleService.toWordCommonIndexList(response, templateDate, tableHead, tableData, wordTemplate, fileName);
参数说明:
response:响应头。
templateDate:Word模板导出的其他匹配数据。
tableHead:表格的表头。可使用Arrays.asList(“序号”, “姓名”)
tableData:表格的内容。
wordTemplate:模板的名称,需要注意路径问题。
fileName:导出的文件对应的文件名。
在模板中配置参数 ${data} 时,可能会出现配置了参数,但是导出的时候赋值不了的情况,生成的Word中仍是 ${data} .
这种情况需要在代码中debug,找到对应的map,从代码中把对应的key复制到Word模板上.
如图所示复制一下,问题就可以解决了
附上材料下载地址
链接:https://pan.baidu.com/s/1jL1UpQatLVIjx0iBXIOMeg 提取码: ga1a
CSDN资源,0积分下载:https://download.csdn.net/download/qq_38254635/12099599
JAVA生成Zip文件并导出:
https://blog.csdn.net/qq_38254635/article/details/127364398
JAVA导出Excel文件:
https://blog.csdn.net/qq_38254635/article/details/126691175
JAVA根据PDF文件生成图片:
https://blog.csdn.net/qq_38254635/article/details/112029941
JAVA根据模板生成PDF文件并导出:
https://blog.csdn.net/qq_38254635/article/details/103919024
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。