先看效果图:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjAzODkxNzU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

public class GeneralTemplateWord2007Util {

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("font", "你好");

params.put("name", "小宝");

params.put("age", "xx");

params.put("sex", "男");

params.put("job", "肉盾");

params.put("hobby", "电商");

params.put("phone", "1717");

        



try {

GeneralTemplateWord2007Util gt = new GeneralTemplateWord2007Util();



Map<String, List<List<String>>> map=new HashMap<String, List<List<String>>>();

map.put("user", gt.generateTestData(5));

map.put("aa", gt.generateTestData(7));

map.put("mytable", gt.generateTestData(11));



gt.templateWrite(filePath, outFile, params, map);

System.out.println("生成模板成功");

} catch (Exception e) {

// TODO Auto-generated catch block

System.out.println("生成模板失败");

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;

}





/**

* 用一个docx文档作为模板,然后替换当中的内容,再写入目标文档中。



* @throws Exception

*/

public void templateWrite(String filePath, String outFile,

Map<String, Object> params, Map<String, List<List<String>>> map)

throws Exception {





InputStream is = new FileInputStream(filePath);

XWPFDocument doc = new XWPFDocument(is);

// 替换段落里面的变量

this.replaceInPara(doc, params);

// 替换表格里面的变量并插入数据

this.insertValueToTable(doc, params, map);

OutputStream os = new FileOutputStream(outFile);

doc.write(os);

this.close(os);

this.close(is);

}





/**

* 替换段落里面的变量



* @param doc

*            要替换的文档

* @param params

*            參数

* @throws Exception 

*/

private void replaceInPara(XWPFDocument doc, Map<String, Object> params) throws Exception {

Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();

XWPFParagraph para;

while (iterator.hasNext()) {

para = iterator.next();

this.replaceInPara(para, params);

}

}





/**

* 替换段落里面的变量



* @param para

*            要替换的段落

* @param params

*            參数

* @throws Exception 

*/

private String replaceInPara(XWPFParagraph para, Map<String, Object> params) throws Exception {

String str=null;

List<XWPFRun> runs;

XWPFRun run = null;

Matcher matcher;

Matcher mr;

int fontSize=0;

boolean setBold=false;

boolean setItalic=false;

UnderlinePatterns setUnderline=null; 

String setColor="";

int setTextPosition=0;

String setFontFamily=null;





if (this.matcher(para.getParagraphText()).find()) {

runs = para.getRuns();

for (int i = 0; i < runs.size(); i++) {

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。

fontSize=run.getFontSize();

setBold=run.isBold();

setItalic=run.isItalic();

setUnderline=run.getUnderline();

setColor=run.getColor();

setTextPosition=run.getTextPosition();

setFontFamily=run.getFontFamily();



para.removeRun(i);

XWPFRun runP = para.insertNewRun(i);



runP.setText(runText);

runP.setBold(setBold);

runP.setItalic(setItalic);

runP.setUnderline(setUnderline);

runP.setColor(setColor);

runP.setTextPosition(setTextPosition);



if(fontSize!=-1) runP.setFontSize(fontSize);

if (setFontFamily != null) runP.setFontFamily(setFontFamily);

}

}

} else if ((mr=this.matcherRow(para.getParagraphText())).find()) {

str=mr.group(1)+"";

}

return str;

}





/**

* 按模版行样式填充数据,暂未实现特殊样式填充(如列合并),仅仅能用于普通样式(如段落间距 缩进 字体 对齐)



* @param doc

*            要替换的文档

* @param params

*            參数

* @param resultList

*            须要遍历的数据

* @throws Exception

*/

private void insertValueToTable(XWPFDocument doc,

Map<String, Object> params, Map<String, List<List<String>>> map)

throws Exception {

Iterator<XWPFTable> iterator = doc.getTablesIterator();

XWPFTable table = null;

List<XWPFTableRow> rows = null;

List<XWPFParagraph> paras;

List<XWPFTableCell> tmpCells = null;// 模版列

XWPFTableRow tmpRow = null;// 匹配用

XWPFTableCell tmpCell = null;// 匹配用

int thisRow = 0;

String str=null;

while (iterator.hasNext()) {

List<XWPFTableCell> cells = null;

List<List<String>> resultList=null;

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) {

str=this.replaceInPara(para, params);

if (str!=null) {

thisRow = i;// 找到模板行

resultList=map.get(str);



tmpRow = rows.get(i - 1);

cells = tmpRow.getTableCells();





}

}

}

}

if (thisRow > 0 && resultList.size()>0) {

this.insertRowToTable(table, tmpRow, tmpCell, thisRow,

resultList, tmpCells, tmpCells);

} else {

System.out.println("该表格中未找到动态标志符");

return;

}

thisRow = 0;

}

}





public void insertRowToTable(XWPFTable table, XWPFTableRow tmpRow,

XWPFTableCell tmpCell, int thisRow, List<List<String>> resultList,

List<XWPFTableCell> tmpCells, List<XWPFTableCell> cells)

throws Exception {

tmpCells = tmpRow.getTableCells();

for (int i = 0, len = resultList.size(); i < len; i++) {

XWPFTableRow row = table.insertNewTableRow(thisRow + i);

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));

}

}

// 删除模版行

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 Matcher matcherRow(String str) {

Pattern pattern = Pattern.compile("\\$\\[(.+?

)\\]",

Pattern.CASE_INSENSITIVE);

Matcher matcher = pattern.matcher(str);

return matcher;

}





/**

* 关闭输入流



* @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();

}

}

}

}

POI动态生成word2007加强版的更多相关文章

  1. java动态生成带下拉框的Excel导入模板

    在实际开发中,由于业务需要,常常需要进行Excel导入导出操作.以前做一些简单的导入时,先准备一个模板,再进行导入,单有十几. 二十几个导入模板时,往往要做十几.二十几个模板.而且,当在模板中需要有下 ...

  2. freemarker动态生成word并将生成的word转为PDF,openoffice转换word乱码

    之前项目有个需求,需要先动态生成word内容,然后再预览生成word的内容(不能修改).整理一下,方便以后使用. 网上参考了好多大神的博客.具体也忘了参考谁的了,如有侵权,请告知修改. 思路一: 将目 ...

  3. poi自动生成Ecxel表格和Chart图表

    最近因为业务需求,需要做poi自动导出Ecxel表格和Chart折线图的功能. 所以我在网上找到了一篇关于poi生成Chart图表的博客,代码很详细,但是缺少相关注释说明. 想要将它改造成自己需要的样 ...

  4. poi实现生成下拉选联动

    在我们实际的程序开发中,经常需要用到从excel导入数据中系统中,而为了防止用户在excel中乱输入文字,有些需要用到下拉选的地方,就需要从程序中动态生成模板.本例子简单的讲解一下,如何生成级联下拉选 ...

  5. Aop动态生成代理类时支持带参数构造函数

    一.背景 在某些情况下,我们需要植入AOP代码的类并没有默认构造函数.那么此时动态生成的代理类也需要相同签名的构造函数,并且内部调用原始类的构造函数.自己折腾了1晚上没搞定,现在搞定了发出来供大家一起 ...

  6. dynamic-css 动态 CSS 库,使得你可以借助 MVVM 模式动态生成和更新 css,从 js 事件和 css 选择器的苦海中脱离出来

    dynamic-css 使得你可以借助 MVVM 模式动态生成和更新 css,从而将本插件到来之前,打散.嵌套在 js 中的修改样式的代码剥离出来.比如你要做元素跟随鼠标移动,或者根据滚动条位置的变化 ...

  7. ABP(现代ASP.NET样板开发框架)系列之20、ABP展现层——动态生成WebApi

    点这里进入ABP系列文章总目录 ABP(现代ASP.NET样板开发框架)系列之20.ABP展现层——动态生成WebApi ABP是“ASP.NET Boilerplate Project (ASP.N ...

  8. 【.NET深呼吸】Zip文件操作(2):动态生成Zip文档

    通过前面一篇烂文的介绍,大伙儿知道,ZipArchive类表示一个zip文档实例,除了用上一篇文章中所列的方法来读写zip文件外,还可以直接通过ZipArchive类,动态生成zip文件. 文件流操作 ...

  9. jquery动态生成的元素添加事件的方法

    动态生成的元素如果要添加事件,要写成 $(document).on("click", "#txtName", function() { alert(this.v ...

随机推荐

  1. RESTful 接口实现简明指南

    REST 简介 REST 是一个术语的缩写,REpresentational State Transfer,中文直译「表征状态转移」,这是个很拗口的词.我的建议是先不要强行理解,直接看怎么做,等对实施 ...

  2. 变量与指针 --- WalMart 寄存箱设计者不懂计算机

    一.场景: 今天星期天,难得公司售后同事很给力,项目运行正常,无运维事务需要处理.于是满足堂客(湖南人称老婆)很久来的心愿 陪其逛街(这里要惭愧 检讨作为IT码农常常容易忽略身边的人.大声疾呼:“码农 ...

  3. python中lambda以及与filter/map/reduce结合的用法

    一.lambda函数即匿名函数,和普通的函数相比,就是省去了函数名称而已: lambda语句中,冒号前是参数,可以有多个,用逗号隔开,冒号右边是函数体的返回值 g = lambda x,y : x+y ...

  4. python 全局解释锁GIL

    Python的全局解释器锁GIL用于保护python解释器,使得任意时刻,只有一个线程在解释器中运行.从而保证线程安全 在多线程环境中,Python 虚拟机按以下方式执行: 1. 设置GIL2. 切换 ...

  5. Oracle 后台进程 详细说明

    一. 进程概述 先来看一下Oracle 11g 的架构图. 看起来比较模糊,我已经上传到了csdn 的下载. 是个pdf 文件, 2m 多. 那个看起来比较清楚. 也对每个进程做了解释. 下载地址:O ...

  6. 【博弈论】【SG函数】poj2311 Cutting Game

    由于异或运算满足结合律,我们把当前状态的SG函数定义为 它所能切割成的所有纸片对的两两异或和之外的最小非负整数. #include<cstdio> #include<set> ...

  7. 【AC自动机+DP】USACO2012 JAN GOLD_Video Game Combos

    [题目大意] 给你个模式串(每个长度≤15,1≤N≤20),串中只含有三种字母.求一长度为K(1≤K≤1000)的字符串,使得匹配数最大(重复匹配计多次),输出最大值. [解题思路] W老师给的题,然 ...

  8. 分析成绩 Exercise07_04

    import java.util.Scanner; /** * @author 冰樱梦 * 时间:2018年下半年 * 题目:分析成绩 * */ public class Exercise07_04 ...

  9. sql-server-linux 官网

    https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-overview

  10. 最短路径之迪杰斯特拉算法的Java实现

    Dijkstra算法是最短路径算法中为人熟知的一种,是单起点全路径算法.该算法被称为是“贪心算法”的成功典范.本文接下来将尝试以最通俗的语言来介绍这个伟大的算法,并赋予java实现代码. 一.知识准备 ...