`
疯不觉
  • 浏览: 7073 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

POI动态生成word2007加强版

    博客分类:
  • word
 
阅读更多

先看效果图:

技术分享

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

}

分享到:
评论

相关推荐

    Java Poi流 根据Word模板插入相应的文本、表格和图片,生成新的Word报告

    在本场景中,我们主要关注如何使用Java POI处理Word文档,特别是通过模板来生成新的Word报告。这个过程涉及到对文本、表格和图片的插入操作,这些都是构建复杂报告的关键元素。 首先,我们要理解Java POI中的...

    POI使用word模板文件循环输出行并导出word

    Word文件本质上是XML格式的,POI通过HWPF(Horizontally-Writeable and Portable Format)组件提供了对旧版Word 97-2003文档的支持,而XWPF(XML Word Processing Format)则用于处理更现代的OpenXML格式的Word文档...

    POI中文帮助文档_POI_

    Apache POI是一个开源项目,主要用于读取和...通过阅读这个“POI中文帮助文档”,开发者将能够熟练地利用Apache POI进行Office文档的编程操作,无论是在数据分析、报表生成还是自动化办公场景中,都能发挥重要作用。

    poi导出word的几种方法

    ### POI导出Word的几种方法 在Java开发过程中,特别是在使用Grails框架时,我们经常需要处理文档的生成和转换任务。其中一种常见的需求就是将数据导出为Word文档。Apache POI库提供了一种非常高效且灵活的方式来...

    POI 中文学习文档(.doc)

    在实际开发中,POI非常适用于生成自定义的报告或数据分析结果,因为它可以方便地创建复杂的表格结构,并且能够精确地控制单元格的样式和数据格式。比如,你可以创建带有多个工作表的工作簿,每个工作表可以包含不同...

    如何在WORD复选框中打勾

    2. **插入带圈字符**:点击顶部菜单栏中的“格式”(在较新版本的Word中可能是“布局”或“设计”),然后选择“中文版式”。在下拉菜单中,你会看到“带圈字符”选项。 3. **选择内容**:在弹出的对话框中,输入你...

    poi 解析word、excel

    "POI中文帮助文档.pdf"是关于POI的中文版参考手册,对于初学者来说非常有用。它详细介绍了如何使用POI的各种API,包括工作簿(Workbook)、工作表(Sheet)、行(Row)和单元格(Cell)等概念,以及如何进行读写操作...

    java itext生成多页的word模板

    6. **转换为Word**:使用Apache POI或Aspose库将生成的PDF转换为Word。这通常涉及到读取PDF,解析其内容,然后在Word文档中重新构造。 注意,由于iText不直接支持Word,转换过程可能会丢失一些格式或特定的Word特性...

    POI中文帮助文档 PDF格式 超详细

    本文档旨在提供一份详尽的中文版Apache POI帮助文档,涵盖了Excel和Word文件的操作方法。 #### 二、Apache POI核心组件介绍 Apache POI项目由多个子项目组成,其中最常用的是HSSF(用于操作`.xls`文件)、XSSF...

    POI中文帮助文档.pdf

    根据提供的文件信息,本文将对“POI中文帮助文档”中的关键知识点进行详细的解析与总结。Apache POI项目提供了一套强大的API,用于处理Microsoft Office格式的文件,特别是Excel(.xls和.xlsx)和Word(.doc和.docx...

    POI word替换关键字,转PDF

    标题提到的"POI word替换关键字,转PDF"涉及两个主要的技术领域:使用Apache POI库处理Microsoft Word文档以及将Word文档转换为PDF格式。以下是对这两个知识点的详细阐述: 首先,Apache POI是Java平台上的一个开源...

    java 生成word 文件jar包

    总的来说,这些jar包为Java开发者提供了一种便捷的方式来生成Word文件,适用于需要动态创建Word文档的场景。通过熟练使用iText,可以有效地提高开发效率,同时保持文档的一致性和专业性。在实际应用中,应根据具体...

    POI所有jar包

    6. **版本更新**:Apache POI不断进行版本迭代,修复已知问题,增加新功能,如对Excel 2007及以上版本的支持,以及增强性能和稳定性。 7. **与其他库的集成**:Apache POI可以与Spring、Hibernate等其他Java框架...

    POI批量导入导出

    此外,POI项目也在不断发展,虽然目前尚未完全支持Word对象,但已经有一些其他库如iText和Apache POI的HDF包提供了对Word文档的支持。 使用POI进行批量操作时,开发人员通常需要将POI库添加到项目中,例如通过Maven...

    最新Apache POI 5.2.3jar包和源码

    Apache POI 是一个开源项目,由Apache软件基金会维护,它提供了API用于读写Microsoft Office格式的文件,如Excel、Word和PowerPoint。最新版本为5.2.3,这个压缩包包含了该版本的jar包和源码,对于开发者来说是进行...

    Poi-tl v1.12.1-API文档(中文版).zip

    资源内容:该资源是Poi-tl v1.12.1的API文档的中文版压缩包。Poi-tl是一个基于Apache POI的开源Java模板引擎,用于生成Word、Excel等Office文档。该API文档详细介绍了Poi-tl v1.12.1的各个类、方法和用法,包括模板...

    Java POI中文教程

    实际上,Apache POI库的功能非常丰富,它不仅包括了处理Excel文件的HSSF接口,还包括了处理Excel 2007+版本的XSSF接口,以及处理Word文档的HWPF和XWPF接口等。开发者在掌握了基本的操作方法后,可以进一步深入学习...

    itext生成word需要的jar包

    `iText`是一个流行的开源库,它提供了在Java中创建和修改PDF文档的功能,同时也支持生成Word...不过,要注意,生成Word文档还有其他方法,比如使用Apache POI库直接操作Word的XML结构,这可能更适合复杂文档的编辑。

    poi3.7完整包

    2. **OOXML支持**: POI 3.7加强了对OOXML的支持,这意味着开发者可以处理2007版之后的Microsoft Office文件,包括.xlsx、.docx和.pptx等。OOXML是一种基于XML的文件格式,它的结构更加开放,有利于数据的长期保存和...

    POI包及API

    Apache POI是一个流行的开源库,专门用于处理Microsoft Office格式的文件,如Excel、Word和PowerPoint。在Java环境中,POI提供了一套丰富的API,使得开发者可以方便地创建、读取和修改这些文件。在标题提到的"POI包...

Global site tag (gtag.js) - Google Analytics