总结之数据导出到word模板——使用poi导出

我们先看看需求:
总结之数据导出到word模板——使用poi导出_第1张图片
我们要在模板标题插入内容,在多个表格中填充数据

先看东西

这里我写了个poi工具类方便操作

import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.poi.POIXMLDocument;
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.openxmlformats.schemas.wordprocessingml.x2006.main.CTBorder;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblBorders;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder;

public class Word2007Util {
	
	/**
	 * Description: 根据指定的参数值、模板,生成 word 文档
	 * @param replaceParamMap 需要替换的参数map
	 * @param doc 文档对象
	 * @return 生成后的 word 文档对象
	 */
	public static XWPFDocument replaceWord(Map replaceParamMap, XWPFDocument doc) {
		try {
			if (replaceParamMap != null && replaceParamMap.size() > 0) {
				// 处理段落
				List paragraphList = doc.getParagraphs();
				processParagraphs1(paragraphList, replaceParamMap, doc);

				// 处理表格
				Iterator it = doc.getTablesIterator();
				while (it.hasNext()) {
					XWPFTable table = it.next();
					List rows = table.getRows();
					for (XWPFTableRow row : rows) {
						List cells = row.getTableCells();
						for (XWPFTableCell cell : cells) {
							List paragraphListTable = cell.getParagraphs();
							processParagraphs1(paragraphListTable, replaceParamMap, doc);
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return doc;
	}
	
	/**
	 * Description: 根据指定的参数值、模板,生成 word 文档
	 * @param replaceParamMap 需要替换的参数map
	 * @param is 文档输入流
	 * @return 生成后的 word 文档对象
	 */
	public static XWPFDocument replaceWord(Map replaceParamMap, InputStream is) {
		try {
			return replaceWord(replaceParamMap, new XWPFDocument(is));
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * Description: 根据指定的参数值、模板,生成 word 文档
	 * @param replaceParamMap 需要替换的参数map
	 * @param docTemplate 文档模版路径
	 * @return 生成后的 word 文档对象
	 */
	public static XWPFDocument replaceWord(Map replaceParamMap, String docTemplate) {
		OPCPackage pack;
		try {
			pack = POIXMLDocument.openPackage(docTemplate);
			return replaceWord(replaceParamMap, new XWPFDocument(pack));
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * Description: 处理段落中的文字和图片替换
	 * @param paragraphList 段落集合
	 * @param replaceParamMap 需要替换的参数map
	 * @param doc 文档对象
	 */
	public static void processParagraphs1(List paragraphList, Map replaceParamMap, XWPFDocument doc) {
		if (paragraphList == null || paragraphList.size() <= 0) {
			return;
		}
		//循环段落
		for (XWPFParagraph paragraph : paragraphList) {
			List runs = paragraph.getRuns();
			//循环每个小节,拼接为一个字符串,避免拆分的时候,误把替换字段标记 拆分
			StringBuffer buffer = new StringBuffer();
			for (XWPFRun xwpfRun : runs) {
				String text = xwpfRun.getText(0);
				if (text == null) {
					continue;
				}
				buffer.append(text);
			}
			//循环替换字段map,替换内容
			String textString = buffer.toString();
			for (Entry entry : replaceParamMap.entrySet()) {
				String key = entry.getKey();
				if (textString.indexOf(key) != -1) {
					//isSetText = true;
					Object value = entry.getValue();
					if(value == null) {
						textString = textString.replace(key, "");
					}
					if (value instanceof Map) {// 图片替换
						// TODO 待实现
					} else {//非map,则将值转换为string类型
						textString = textString.replace(key, StringUtil.isNotEmpty(String.valueOf(value)) ? String.valueOf(value) : "");
					}
				}
			}
			//再次循环 把替换后的字符串 赋值给每个段落的最后一个小节,前面的小节全部设为空
			for(int i=0;i") !=-1){
						String s[] = textString.split("
"); for (int j = 0; j < s.length; j++) { run.setText(s[j],j); if(j paragraphList, Map replaceParamMap, XWPFDocument doc) { if (paragraphList == null || paragraphList.size() <= 0) { return; } for (XWPFParagraph paragraph : paragraphList) { List runs = paragraph.getRuns(); for (XWPFRun run : runs) { String text = run.getText(0); if (text == null) { continue; } boolean isSetText = false; for (Entry entry : replaceParamMap.entrySet()) { String key = entry.getKey(); if (text.indexOf(key) != -1) { isSetText = true; Object value = entry.getValue(); if(value == null) { text = text.replace(key, ""); } if (value instanceof String || value instanceof Integer || value instanceof Float || value instanceof Double) {// 文本替换 text = text.replace(key, StringUtil.isNotEmpty(value.toString()) ? value.toString() : "-"); } if (value instanceof Map) {// 图片替换 // TODO 待实现 } } } if (isSetText) { run.setText(text, 0); } } } } /** * Description: 将输入流中的数据写入字节数组 * @param in 输入流 * @param isClose 是否关闭输入流 * @return 字节数组 */ public static byte[] inputStream2ByteArray(InputStream in, boolean isClose) { byte[] byteArray = null; try { int total = in.available(); byteArray = new byte[total]; in.read(byteArray); } catch (IOException e) { e.printStackTrace(); } finally { if (isClose) { try { in.close(); } catch (Exception e2) { System.out.println("关闭流失败"); } } } return byteArray; } /** * 取消表格边框 */ public static void removeTableBroder(XWPFTable table){ /**************************************/ CTTblBorders borders=table.getCTTbl().getTblPr().addNewTblBorders(); CTBorder hBorder=borders.addNewInsideH(); hBorder.setVal(STBorder.Enum.forString("none")); hBorder.setSz(new BigInteger("1")); hBorder.setColor("0000FF"); CTBorder vBorder=borders.addNewInsideV(); vBorder.setVal(STBorder.Enum.forString("none")); vBorder.setSz(new BigInteger("1")); vBorder.setColor("00FF00"); CTBorder lBorder=borders.addNewLeft(); lBorder.setVal(STBorder.Enum.forString("none")); lBorder.setSz(new BigInteger("1")); lBorder.setColor("3399FF"); CTBorder rBorder=borders.addNewRight(); rBorder.setVal(STBorder.Enum.forString("none")); rBorder.setSz(new BigInteger("1")); rBorder.setColor("F2B11F"); CTBorder tBorder=borders.addNewTop(); tBorder.setVal(STBorder.Enum.forString("none")); tBorder.setSz(new BigInteger("1")); tBorder.setColor("C3599D"); CTBorder bBorder=borders.addNewBottom(); bBorder.setVal(STBorder.Enum.forString("none")); bBorder.setSz(new BigInteger("1")); bBorder.setColor("F7E415"); } /** * 设置单元格样式 */ public static void setCellStyle(XWPFTableCell cell,String text,String fontFamily){ cell.removeParagraph(0); cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER); //垂直居中 XWPFParagraph paragraphX = cell.addParagraph(); paragraphX.setFontAlignment(2); XWPFRun run = paragraphX.createRun(); run.setFontFamily(fontFamily); run.setText(text); } }

调用Controller

public class ExportController {

    @Autowired
    private ProjectApplyFlowService projectApplyFlowService;

    @Autowired
    private SpecialInfoService specialInfoService;

    @Autowired
    private StartSpecialInfoService startSpecialInfoService;
    /***
    * @Param [id, request, response]
    * @return void
    * @Description 导出项目汇总表
    * @author liuzonghua
    * @date 2020/6/30 17:48
    **/
    @RequestMapping("exportSpecialProject")
    public void expertSpecialProject(String id, HttpServletRequest request, HttpServletResponse response){
        try {
            InputStream in = ResourceUtil.getResourceAsStream("/doc/applyCollectTable.docx");
            XWPFDocument doc = null;

            //数据
            SearchCondition jqGridSearch = new JQGridSearch();

            User currentUser = (User) this.getCurrentUser(request, response);
            ConditionGroupsBuilder conditionGroupsBuilder = new ConditionGroupsBuilder();
            conditionGroupsBuilder.addConditionField(new ConditionField("", "areaDepartmentId", ConditionFieldOp.BASE_EQUAL, currentUser.getDepartmentId()));
            if(StringUtils.isNotBlank(id)) {
                conditionGroupsBuilder.addConditionField(new ConditionField("", "projectBatchId", ConditionFieldOp.BASE_EQUAL, id));
            }
            jqGridSearch.addExtraConditionGroups(conditionGroupsBuilder.build());
            //word多表结构(可再封装方法)
            List>> data = new ArrayList<>();
            List> list = projectApplyFlowService.findCollectByProjectBatchIdAndAreaDepartmentId(id,currentUser.getDepartmentId());
            data.add(list);
            StartSpecialInfo startSpecialInfo = startSpecialInfoService.findById(id);
            if(CollectionUtil.isNotEmpty(startSpecialInfo)){
                SpecialInfo specialInfo = specialInfoService.findById(startSpecialInfo.getSpecialId());
                if(CollectionUtil.isNotEmpty(specialInfo)){
                    doc = this.exportListDoc(in, data,specialInfo.getSpecialName());
                }
            }

            String fileName =  "项目申报汇总表"+ ".docx";
            response.reset();
            this.setDownloadResponse(request, response, fileName);
            ByteArrayOutputStream ostream = new ByteArrayOutputStream();
            ServletOutputStream servletOS = response.getOutputStream();
            doc.write(ostream);
            servletOS.write(ostream.toByteArray());
            servletOS.flush();
            servletOS.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
    * @Param [in, data, specialName]
    * @return org.apache.poi.xwpf.usermodel.XWPFDocument
    * @Description 导出doc
    * @author liuzonghua
    * @date 2020/6/30 17:49
    **/
    public XWPFDocument exportListDoc(InputStream in, List>> data,String specialName) {
        Map map = new LinkedHashMap();
        map.put("${special}", specialName);
        XWPFDocument doc = Word2007Util.replaceWord(map, in);
        docList(data, doc);
        return doc;
    }

    /**
     * 导出列表
     * @param data
     * @param doc
     * Description:
     * Date: 2019年9月27日
     * Time: 上午10:27:47
     * @author liu.zonghua
     */
    private void docList(List>> data,XWPFDocument doc){
        //得到表格对象列表
        List tables = doc.getTables();
        for(int j=0;j map : data.get(j)){
                    //取第j+1个列表
                    XWPFTable table = tables.get(j);
                    //获取表格行对象
                    XWPFTableRow row = null;
                    row = table.createRow();
                    XWPFTableCell cell0 = row.getCell(0);
                    Word2007Util.setCellStyle(cell0, StringUtil.parseString(i + 1),"仿宋");
                    XWPFTableCell cell1 = row.getCell(1);
                    Word2007Util.setCellStyle(cell1, MapUtils.getString(map, "title","") ,"仿宋");
                    XWPFTableCell cell2 = row.getCell(2);
                    Word2007Util.setCellStyle(cell2,MapUtils.getString(map, "startNum",""),"仿宋");
                    XWPFTableCell cell3 = row.getCell(3);
                    Word2007Util.setCellStyle(cell3,MapUtils.getString(map, "projectLeader",""),"仿宋");
                    XWPFTableCell cell4 = row.getCell(4);
                    Word2007Util.setCellStyle(cell4, MapUtils.getString(map, "phone",""),"仿宋");
                    XWPFTableCell cell5 = row.getCell(5);
                    Word2007Util.setCellStyle(cell5, MapUtils.getString(map, "enterpriseStartTime",""),"仿宋");
                    XWPFTableCell cell6 = row.getCell(6);
                    Word2007Util.setCellStyle(cell6, MapUtils.getString(map, "enterpriseEndTime",""),"仿宋");
                    i++;
                }
            }else {
                //取第j+1个列表
                XWPFTable table = tables.get(j);
                //获取表格行对象
                XWPFTableRow row = null;
                row = table.createRow();
                XWPFTableCell cell0 = row.getCell(0);
                Word2007Util.setCellStyle(cell0,"","仿宋");
                XWPFTableCell cell1 = row.createCell();
                Word2007Util.setCellStyle(cell1, "","仿宋");
                XWPFTableCell cell2 = row.createCell();
                Word2007Util.setCellStyle(cell2, "","仿宋");
                XWPFTableCell cell3 = row.createCell();
                Word2007Util.setCellStyle(cell3, "","仿宋");
                XWPFTableCell cell4 = row.createCell();
                Word2007Util.setCellStyle(cell4, "","仿宋");
                XWPFTableCell cell5 = row.createCell();
                Word2007Util.setCellStyle(cell5, "","仿宋");
            }
        }

    }
    /***
    * @Param [request, response, fileName]
    * @return void
    * @Description 下载相关
    * @author liuzonghua
    * @date 2020/6/30 17:49
    **/
    public void setDownloadResponse(HttpServletRequest request, HttpServletResponse response,
                                    String fileName) throws Exception {
        response.setCharacterEncoding("utf-8");
        response.setContentType("multipart/form-data");
        String downloadFileName = "";
        if (request.getHeader("User-Agent").toUpperCase().indexOf("MSIE") > 0) {
            downloadFileName = URLEncoder.encode(fileName, "UTF-8");
        } else {
            downloadFileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
        }
        response.setHeader("Content-disposition", "attachment; filename=" + downloadFileName);
    }
}

解析

 public XWPFDocument exportListDoc(InputStream in, List>> data,String specialName) {
        Map map = new LinkedHashMap();
        map.put("${special}", specialName);
        XWPFDocument doc = Word2007Util.replaceWord(map, in);
        docList(data, doc);
        return doc;
    }

这块来替换word中${}数据

得到多个表格对象

List tables = doc.getTables();

通过List>数据来与表格对应

然后获取表格,填充内容,设置样式。

//获取表格行对象
                    XWPFTableRow row = null;
                    row = table.createRow();
                    XWPFTableCell cell0 = row.getCell(0);
                    Word2007Util.setCellStyle(cell0, StringUtil.parseString(i + 1),"仿宋");

你可能感兴趣的:(java及javaweb)