POI动态生成word2007加强版

先看效果图:

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

}

}

}

}

时间: 2024-11-17 06:34:02

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

poi 动态生成多表头execl

如果所示,我要导出的数据界面是下面这样的,前面样品编号.样品名称.炉次为主表数据,而检验结果是子表数据,这里子表的数据作为了主表的数据的一个字段(集合属性),下面代码会给大家看vo结构 下图为要导出的execl效果 开发思路: 1.该表头表体是根据主表样品名称不同而子表元素个数就会不同,所以第一步就是将前端传来的数据按样品名称分组 2.由于导出的数据顺序会乱,所以还是需要map排序下,这里我们可以按key排序 3.由于我要导出的数据是主子表结构,所以要将表体数据利用反射映射到表头去,以方便导出使

数据库与Excel报表的动态生成

一.数据库与Excel报表的动态生成 (1)读取数据库的数据动态生成Excel报表,这是JSP应用中常遇到的问题,本节采用的基本方法是: 在Excel工作薄中,将报表模板制作在第一张工作表中,从数据库中读取数据,利用POI组件复制模板工作表 而得到一张新的工作表,将查询数据填写到新的工作表中. (2) 实例分析 写一个Servlet程序,查询pubs数据库的titles表和sales表,把查询结果集数据填写到图6-14的报表中, 操作步骤如下: 第1步:新建一个名类为"DBExcelServle

C# 动态生成WebService,无需添加引用

C#项目调用WebService是很常见的现象,但一旦修改链接地址就需要重新更新引用很是麻烦,这里跟大家分享一个通过地址,无需添加引用动态生成Webservice的小方法 方法类: 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.ServiceModel; 6 using System.ServiceModel.Channels

C++实现根据类名动态生成类对象

在开发后台服务的过程中,我们常常需要从数据库中取数据,并将数据缓存在本地中,另外,我们的服务还需要有更新数据的能力:包括定时的主动更新以及数据库数据更新时服务收到通知的被动更新. 之前在需要用到以上功能的时候,模仿着组内通用的数据Cache部分的代码来写,十分方便,基本上只需要自己写两个类:一个是取数据并缓存数据的类XXXData,一个是扇出数据的类XXXFetcher. 在需要使用数据的时候,通过: FetcherFactory::getFetcher<XXXFetcher>() 即可获取一

[搬运自我的CSDN博客] python抓取javascript动态生成HTML内容的实践

<注:CSDN博客在美国访问特别卡,所以转移到cnblogs来发文章> 本实验在Ubuntu14.04上完成.使用的浏览器是火狐(Firefox 33.0),python版本是2.7.6. 大家都知道用urllib配合正则表达式抓取静态HTML的内容很方便,但是如果网页中有javascript动态生成的内容,urllib就无能为力了. 此时我们要借助一个额外的工具:selenium.它的工作原理是操纵(火狐)浏览器浏览目标网页,等待网页中的javascript全部执行完毕后再对HTML源码进行

动态生成二级菜单

现在越来越多的用到二级甚至多级菜单,前台菜单的显示,手动指定也越来越不能满足要求,所以,动态生成菜单是必须的 思路 + 示例代码(以二级菜单为例) 先取出一级菜单内容值,接下来遍历一级菜单,将其id当做本次检索的parentid,将与之对应的二级菜单值获取到, 并加入到当前数组中(后台) 二层循环,当获取一个值时,检查其对于的二级菜单项是否有数据,有的话,则输出来,没有则跳过(前台) 以PHP后台为例 $res = mysql_query('*** where parentid = 0');  

nginx利用image_filter动态生成缩略图

原文:http://www.open-open.com/lib/view/open1416193847945.html "我现在是有些图片需要生成缩略图,这个现在加了image_filter这个已经实现了,但我不知道怎么样才能访问我上传的原图" 刚开始觉得也不太好弄,让他用程序区处理,实际上稍微动脑筋分析一下也可以不修改程序实现动态生成缩略图且能够访问原图. 前提是需要定好图片的访问规则. 先来看一下什么是nginx的image filter模块. HttpImageFilterMod

动态生成随机背景色表格

<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>动态生成随机背景色表格</title> <style> table{margin-top:20px;width:800px;border:1px solid #ddd;border-collapse:collapse;} td{border:1px solid #ddd;padding:

Android动态生成表格

最近刚刚学习完Android的五大布局,现在我们进一步深入学习,尝试做一个动态生成表格功能的例子 样式布局代码如下: 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4