標籤:poi
效果看到瞭然後看代碼,代碼中方法都有注釋就不多說廢話了:
“`
package com.poi;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
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.CTFonts;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTInd;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSpacing;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
public class GeneralTemplateDOCX {
/** * @param args */public static void main(String[] args) { // TODO Auto-generated method stub String filePath = "C:/Users/Administrator/Desktop/doc/模板.docx"; String outFile = "C:/Users/Administrator/Desktop/產生模板.docx"; Map<String, Object> params = new HashMap<String, Object>(); params.put("myTable","我的表格" ); params.put("name", "小寶"); params.put("age", "xx"); params.put("sex", "男"); params.put("job", "肉盾"); params.put("hobby", "電商"); params.put("phone", "1717"); try { GeneralTemplateDOCX gt = new GeneralTemplateDOCX(); gt.templateWrite(filePath, outFile, params, gt.generateTestData(10)); System.out.println("產生模板成功"); } catch (Exception e) { // TODO Auto-generated catch block System.out.println("產生模板失敗"); e.printStackTrace(); }}/** * 用一個docx文檔作為模板,然後替換其中的內容,再寫入目的文件中。 * * @throws Exception */public void templateWrite(String filePath, String outFile, Map<String, Object> params,List<List<String>> resultList) throws Exception { InputStream is = new FileInputStream(filePath); XWPFDocument doc = new XWPFDocument(is); // 替換段落裡面的變數 this.replaceInPara(doc, params); // 替換表格裡面的變數並插入資料 this.insertValueToTable(doc, params,resultList); OutputStream os = new FileOutputStream(outFile); doc.write(os); this.close(os); this.close(is);}/** * 替換段落裡面的變數 * * @param doc * 要替換的文檔 * @param params * 參數 */private void replaceInPara(XWPFDocument doc, Map<String, Object> params) { Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator(); XWPFParagraph para; while (iterator.hasNext()) { para = iterator.next(); this.replaceInPara(para, params); }}/** * 替換段落裡面的變數 * * @param para * 要替換的段落 * @param params * 參數 */private boolean replaceInPara(XWPFParagraph para, Map<String, Object> params) { boolean data = false; List<XWPFRun> runs; Matcher matcher; if (this.matcher(para.getParagraphText()).find()) { runs = para.getRuns(); for (int i = 0; i < runs.size(); i++) { XWPFRun run = runs.get(i); String runText = run.toString(); matcher = this.matcher(runText); if (matcher.find()) { while ((matcher = this.matcher(runText)).find()) { runText = matcher.replaceFirst(String.valueOf(params .get(matcher.group(1)))); } // 直接調用XWPFRun的setText()方法設定文本時,在底層會重新建立一個XWPFRun,把文本附加在當前文本後面, // 所以我們不能直接設值,需要先刪除當前run,然後再自己手動插入一個新的run。 para.removeRun(i); para.insertNewRun(i).setText(runText); } } } else if (this.matcherRow(para.getParagraphText())) { runs = para.getRuns(); System.out.println("run " + runs); data = true; } return data;}/** * 按模版行樣式填充資料,暫未實現特殊樣式填充(如列合并),只能用於普通樣式(如段落間距 縮排 字型 對齊) * * @param doc * 要替換的文檔 * @param params * 參數 * @param resultList * 需要遍曆的資料 * @throws Exception */private void insertValueToTable(XWPFDocument doc, Map<String, Object> params,List<List<String>> resultList) throws Exception { Iterator<XWPFTable> iterator = doc.getTablesIterator(); XWPFTable table = null; List<XWPFTableRow> rows = null; List<XWPFTableCell> cells = null; List<XWPFParagraph> paras; List<XWPFTableCell> tmpCells = null;// 模版列 XWPFTableRow tmpRow = null;// 匹配用 XWPFTableCell tmpCell = null;// 匹配用 boolean flag = false;// 是否找到表格 int thisRow=0; while (iterator.hasNext()) { table = iterator.next(); rows = table.getRows(); for (int i = 1; i <= rows.size(); i++) { cells = rows.get(i-1).getTableCells(); for (XWPFTableCell cell : cells) { paras = cell.getParagraphs(); for (XWPFParagraph para : paras) { if (this.replaceInPara(para, params)) { System.out.println("this.row=" + i); thisRow=i;//找到模板行 tmpRow = rows.get(i - 1); cells = tmpRow.getTableCells(); System.out.println("cells.size()=" + cells.size() + " resultList.get(0).size()=" + resultList.get(0).size()); if (cells.size() == resultList.get(0).size()) { flag = true; break; } } } } } } if (!flag) { System.out.println("未找到表格"); return; } tmpCells = tmpRow.getTableCells(); for (int i = 0, len = resultList.size(); i < len; i++) { System.out.println("開始寫第" + i + "行"); XWPFTableRow row = table.createRow(); row.setHeight(tmpRow.getHeight()); List<String> list = resultList.get(i); cells = row.getTableCells(); // 插入的行會填充與表格第一行相同的列數 for (int k = 0, klen = cells.size(); k < klen; k++) { tmpCell = tmpCells.get(k); XWPFTableCell cell = cells.get(k); setCellText(tmpCell, cell, list.get(k)); } // 繼續寫剩餘的列 for (int j = cells.size(), jlen = list.size(); j < jlen; j++) { tmpCell = tmpCells.get(j); XWPFTableCell cell = row.addNewTableCell(); setCellText(tmpCell, cell, list.get(j)); System.out.println("內容" + list.get(j)); } } // 刪除模版行 table.removeRow(thisRow - 1);}public void setCellText(XWPFTableCell tmpCell, XWPFTableCell cell, String text) throws Exception { CTTc cttc2 = tmpCell.getCTTc(); CTTcPr ctPr2 = cttc2.getTcPr(); CTTc cttc = cell.getCTTc(); CTTcPr ctPr = cttc.addNewTcPr(); cell.setColor(tmpCell.getColor()); // cell.setVerticalAlignment(tmpCell.getVerticalAlignment()); if (ctPr2.getTcW() != null) { ctPr.addNewTcW().setW(ctPr2.getTcW().getW()); } if (ctPr2.getVAlign() != null) { ctPr.addNewVAlign().setVal(ctPr2.getVAlign().getVal()); } if (cttc2.getPList().size() > 0) { CTP ctp = cttc2.getPList().get(0); if (ctp.getPPr() != null) { if (ctp.getPPr().getJc() != null) { cttc.getPList().get(0).addNewPPr().addNewJc() .setVal(ctp.getPPr().getJc().getVal()); } } } if (ctPr2.getTcBorders() != null) { ctPr.setTcBorders(ctPr2.getTcBorders()); } XWPFParagraph tmpP = tmpCell.getParagraphs().get(0); XWPFParagraph cellP = cell.getParagraphs().get(0); XWPFRun tmpR = null; if (tmpP.getRuns() != null && tmpP.getRuns().size() > 0) { tmpR = tmpP.getRuns().get(0); } XWPFRun cellR = cellP.createRun(); cellR.setText(text); // 複製字型資訊 if (tmpR != null) { cellR.setBold(tmpR.isBold()); cellR.setItalic(tmpR.isItalic()); cellR.setStrike(tmpR.isStrike()); cellR.setUnderline(tmpR.getUnderline()); cellR.setColor(tmpR.getColor()); cellR.setTextPosition(tmpR.getTextPosition()); if (tmpR.getFontSize() != -1) { cellR.setFontSize(tmpR.getFontSize()); } if (tmpR.getFontFamily() != null) { cellR.setFontFamily(tmpR.getFontFamily()); } if (tmpR.getCTR() != null) { if (tmpR.getCTR().isSetRPr()) { CTRPr tmpRPr = tmpR.getCTR().getRPr(); if (tmpRPr.isSetRFonts()) { CTFonts tmpFonts = tmpRPr.getRFonts(); CTRPr cellRPr = cellR.getCTR().isSetRPr() ? cellR .getCTR().getRPr() : cellR.getCTR().addNewRPr(); CTFonts cellFonts = cellRPr.isSetRFonts() ? cellRPr .getRFonts() : cellRPr.addNewRFonts(); cellFonts.setAscii(tmpFonts.getAscii()); cellFonts.setAsciiTheme(tmpFonts.getAsciiTheme()); cellFonts.setCs(tmpFonts.getCs()); cellFonts.setCstheme(tmpFonts.getCstheme()); cellFonts.setEastAsia(tmpFonts.getEastAsia()); cellFonts.setEastAsiaTheme(tmpFonts.getEastAsiaTheme()); cellFonts.setHAnsi(tmpFonts.getHAnsi()); cellFonts.setHAnsiTheme(tmpFonts.getHAnsiTheme()); } } } } // 複製段落資訊 cellP.setAlignment(tmpP.getAlignment()); cellP.setVerticalAlignment(tmpP.getVerticalAlignment()); cellP.setBorderBetween(tmpP.getBorderBetween()); cellP.setBorderBottom(tmpP.getBorderBottom()); cellP.setBorderLeft(tmpP.getBorderLeft()); cellP.setBorderRight(tmpP.getBorderRight()); cellP.setBorderTop(tmpP.getBorderTop()); cellP.setPageBreak(tmpP.isPageBreak()); if (tmpP.getCTP() != null) { if (tmpP.getCTP().getPPr() != null) { CTPPr tmpPPr = tmpP.getCTP().getPPr(); CTPPr cellPPr = cellP.getCTP().getPPr() != null ? cellP .getCTP().getPPr() : cellP.getCTP().addNewPPr(); // 複製段落間距資訊 CTSpacing tmpSpacing = tmpPPr.getSpacing(); if (tmpSpacing != null) { CTSpacing cellSpacing = cellPPr.getSpacing() != null ? cellPPr .getSpacing() : cellPPr.addNewSpacing(); if (tmpSpacing.getAfter() != null) { cellSpacing.setAfter(tmpSpacing.getAfter()); } if (tmpSpacing.getAfterAutospacing() != null) { cellSpacing.setAfterAutospacing(tmpSpacing .getAfterAutospacing()); } if (tmpSpacing.getAfterLines() != null) { cellSpacing.setAfterLines(tmpSpacing.getAfterLines()); } if (tmpSpacing.getBefore() != null) { cellSpacing.setBefore(tmpSpacing.getBefore()); } if (tmpSpacing.getBeforeAutospacing() != null) { cellSpacing.setBeforeAutospacing(tmpSpacing .getBeforeAutospacing()); } if (tmpSpacing.getBeforeLines() != null) { cellSpacing.setBeforeLines(tmpSpacing.getBeforeLines()); } if (tmpSpacing.getLine() != null) { cellSpacing.setLine(tmpSpacing.getLine()); } if (tmpSpacing.getLineRule() != null) { cellSpacing.setLineRule(tmpSpacing.getLineRule()); } } // 複製段落縮排資訊 CTInd tmpInd = tmpPPr.getInd(); if (tmpInd != null) { CTInd cellInd = cellPPr.getInd() != null ? cellPPr.getInd() : cellPPr.addNewInd(); if (tmpInd.getFirstLine() != null) { cellInd.setFirstLine(tmpInd.getFirstLine()); } if (tmpInd.getFirstLineChars() != null) { cellInd.setFirstLineChars(tmpInd.getFirstLineChars()); } if (tmpInd.getHanging() != null) { cellInd.setHanging(tmpInd.getHanging()); } if (tmpInd.getHangingChars() != null) { cellInd.setHangingChars(tmpInd.getHangingChars()); } if (tmpInd.getLeft() != null) { cellInd.setLeft(tmpInd.getLeft()); } if (tmpInd.getLeftChars() != null) { cellInd.setLeftChars(tmpInd.getLeftChars()); } if (tmpInd.getRight() != null) { cellInd.setRight(tmpInd.getRight()); } if (tmpInd.getRightChars() != null) { cellInd.setRightChars(tmpInd.getRightChars()); } } } }}/** * 正則匹配字串 * * @param str * @return */private Matcher matcher(String str) { Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(str); return matcher;}/** * 正則匹配字串 * * @param str * @return */private boolean matcherRow(String str) { Pattern pattern = Pattern.compile("\\$\\[(.+?)\\]", Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(str); return matcher.find();}/** * 關閉輸入資料流 * * @param is */private void close(InputStream is) { if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } }}/** * 關閉輸出資料流 * * @param os */private void close(OutputStream os) { if (os != null) { try { os.close(); } catch (IOException e) { e.printStackTrace(); } }}// 產生測試資料public List<List<String>> generateTestData(int num) { List<List<String>> resultList = new ArrayList<List<String>>(); for (int i = 1; i <= num; i++) { List<String> list = new ArrayList<String>(); list.add("" + i); list.add("測試_" + i); list.add("測試2_" + i); list.add("測試3_" + i); list.add("測試4_" + i); list.add("測試5_" + i); resultList.add(list); } return resultList;}
}
“`這段代碼在段落文字上未處理,需要的自己加上set方法。
java 填寫模板表格和動態產生表格