總結之數據導出到word模板——使用poi導出

我們先看看需求:
在這裏插入圖片描述
我們要在模板標題插入內容,在多個表格中填充數據

先看東西

這裏我寫了個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<String, Object> replaceParamMap, XWPFDocument doc) {
		try {
			if (replaceParamMap != null && replaceParamMap.size() > 0) {
				// 處理段落
				List<XWPFParagraph> paragraphList = doc.getParagraphs();
				processParagraphs1(paragraphList, replaceParamMap, doc);

				// 處理表格
				Iterator<XWPFTable> it = doc.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();
							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<String, Object> 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<String, Object> 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<XWPFParagraph> paragraphList, Map<String, Object> replaceParamMap, XWPFDocument doc) {
		if (paragraphList == null || paragraphList.size() <= 0) {
			return;
		}
		//循環段落
		for (XWPFParagraph paragraph : paragraphList) {
			List<XWPFRun> 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<String, Object> 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<runs.size();i++){
				XWPFRun run = runs.get(i);
				if(i<(runs.size()-1)){
					run.setText(null, 0);
				}else{
					//如果內容裏面有換行標籤  需要替換掉換行標籤  並加入換行功能
					if(textString.indexOf("<br>") !=-1){
						String s[] = textString.split("<br>");
						for (int j = 0; j < s.length; j++) {
							run.setText(s[j],j);
							if(j<s.length-1){
							run.addBreak();	//換行
							}
						}
								
					}else{
						run.setText(textString, 0);
					}
				}
			}
		}
	}
	/**
	 * Description: 處理段落中的文字和圖片替換
	 * @param paragraphList 段落集合
	 * @param replaceParamMap 需要替換的參數map
	 * @param doc 文檔對象
	 */
	public static void processParagraphs(List<XWPFParagraph> paragraphList, Map<String, Object> replaceParamMap, XWPFDocument doc) {
		if (paragraphList == null || paragraphList.size() <= 0) {
			return;
		}
		for (XWPFParagraph paragraph : paragraphList) {
			List<XWPFRun> runs = paragraph.getRuns();
			for (XWPFRun run : runs) {
				String text = run.getText(0);
				if (text == null) {
					continue;
				}
				boolean isSetText = false;
				for (Entry<String, Object> 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<List<Map<String, Object>>> data = new ArrayList<>();
            List<Map<String, Object>> 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<List<Map<String, Object>>> data,String specialName) {
        Map<String, Object> map = new LinkedHashMap<String, Object>();
        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<List<Map<String, Object>>> data,XWPFDocument doc){
        //得到表格對象列表
        List<XWPFTable> tables = doc.getTables();
        for(int j=0;j<data.size();j++) {
            if(CollectionUtil.isNotEmpty(data.get(j))){
                int i = 0;
                for(Map<String, Object> 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<List<Map<String, Object>>> data,String specialName) {
        Map<String, Object> map = new LinkedHashMap<String, Object>();
        map.put("${special}", specialName);
        XWPFDocument doc = Word2007Util.replaceWord(map, in);
        docList(data, doc);
        return doc;
    }

這塊來替換word中${}數據

得到多個表格對象

List<XWPFTable> tables = doc.getTables();

通過List<List<Map<String, Object>>數據來與表格對應

然後獲取表格,填充內容,設置樣式。

//獲取表格行對象
                    XWPFTableRow row = null;
                    row = table.createRow();
                    XWPFTableCell cell0 = row.getCell(0);
                    Word2007Util.setCellStyle(cell0, StringUtil.parseString(i + 1),"仿宋");
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章