假如碰到poi载入例如{name}不可以鉴别为一个总体,可以应用word的域操作,假如不太清晰域的应用,可以那么操作,先往text文档中写好,例如{name},随后再全部拷贝到word中,不必一个一个在word中敲,要不然有可能不可能被poi鉴别为一个总体
XWPFDocument对象
POI是apache给予的可以操作word文档的第三方jar。POI能操作word是应用XWPFDocument对象。
- XWPFDocument对象可以解析docx文件,在XWPFDocument对象根据键入流解析docx的情况下,会获取到docx文档中的各种各样对象,例如报表,文段,照片等,根据操作XWPFDocument对象就可以改动模板內容
- XWPFDocument API构造org.apache.poi.xwpf.usermodel.XWPFDocument
- XWPFDocument 给予write(OutputStream stream)方式将调整后的对象再次载入xml并形成新的docx
根据XWPFDocument 可以取得的docx中的各种各样对象
要实际操作根据XWPFDocument 可以取得的docx中的各种各样对象,大家离不了一个对象为XWPFRun对象,API构造
org.apache.poi.xwpf.usermodel.XWPFRun。其叙述为:XWPFRun object defines a region of text with a common set of properties。根据叙述大家不难理解其功效为设定文字对象的各类特性。
根据XWPFDocument 获取对象
//解析docx模板并获取document对象
XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
//获取全部文字对象
List<XWPFParagraph> allParagraph = document.getParagraphs();
//获取全部报表对象
List<XWPFTable> allTable = document.getTables();
//获取照片对象
XWPFPictureData pic = document.getPictureDataByID(\"PICId\");
最先建一个很容易的word模板001.docx,大家根据操作对象获取word中的文字內容
下边demo的输入输出可以看到大家操作文字对象,取得成功获取了文字內容
@Component(\"xWPRUNTest\")
public class XWPRUNTest {
//模板文档详细地址
private static String inputUrl = \"C:\\Users\\zhihe\\Desktop\\demo\\001.docx\";
public void runTest(){
try {
//解析docx模板并获取document对象
XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
//获取全部文字对象
List<XWPFParagraph> allParagraph = document.getParagraphs();
//获取XWPFRun对象导出全部文字內容
StringBuffer tempText = new StringBuffer();
for (XWPFParagraph xwpfParagraph : allParagraph) {
List<XWPFRun> runList = xwpfParagraph.getRuns();
for (XWPFRun xwpfRun : runList) {
tempText.append(xwpfRun.toString());
}
}
System.out.println(tempText.toString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
检测
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(\"classpath:applicationContext.xml\")
public class runTest {
@Resource
private XWPRUNTest xWPRUNTest;
@Test
public void runTest(){
xWPRUNTest.runTest();
}
}
控制面板导出结论
在这儿发觉操作文字对象的情况下并并没有获取到报表文字,因此如果我们必须获取到报表文字还要另一个的操作
@Component(\"xWPRUNTableTest\")
public class XWPRUNTableTest {
//模板文档详细地址
private static String inputUrl = \"C:\\Users\\zhihe\\Desktop\\demo\\001.docx\";
public void tableTest(){
try {
StringBuffer tableText = new StringBuffer();
//解析docx模板并获取document对象
XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
//获取所有报表对象
List<XWPFTable> allTable = document.getTables();
for (XWPFTable xwpfTable : allTable) {
//获取表格行数据信息
List<XWPFTableRow> rows = xwpfTable.getRows();
for (XWPFTableRow xwpfTableRow : rows) {
//获取报表表格中数据信息
List<XWPFTableCell> cells = xwpfTableRow.getTableCells();
for (XWPFTableCell xwpfTableCell : cells) {
List<XWPFParagraph> paragraphs = xwpfTableCell.getParagraphs();
for (XWPFParagraph xwpfParagraph : paragraphs) {
List<XWPFRun> runs = xwpfParagraph.getRuns();
for(int i = 0; i < runs.size();i ){
XWPFRun run = runs.get(i);
tableText.append(run.toString());
}
}
}
}
}
System.out.println(tableText.toString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
检测
取得成功获取报表
下边大家来对一个wrod开展简洁的改动,最先有一个模板word,里边仅有几个字
编码
public class FirstWordTest {
//模板文档详细地址
private static String inputUrl = \"C:\\Users\\zhihe\\Desktop\\demo\\001.docx\";
//新制造的模板文档
private static String outputUrl = \"C:\\Users\\zhihe\\Desktop\\demo\\test.docx\";
/**
*
* @param inputUrl 模板路径
* @param outputUrl 模板储存路径
*/
public static void changeWord(String inputUrl, String outputUrl ){
try {
//获得word文档分析对象
XWPFDocument doucument = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
//获得文段文字对象
List<XWPFParagraph> paragraph = doucument.getParagraphs();
//获得第一行run对象
XWPFRun run = paragraph.get(0).getRuns().get(0);
//设定文字內容
run.setText(\"改动了的word\");
//生成新的word
File file = new File(outputUrl);
FileOutputStream stream = new FileOutputStream(file);
doucument.write(stream);
stream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
changeWord(inputUrl,outputUrl);
}
}
检测
运作后生成新的word
可是在具体项目中并并没有那么简单,模板文本文档中很有可能必须更换文字中的文本,也有可能必须更换报表对象中的文本,或是在特定报表中插进数据信息,下边咱们就模仿实际情况来做一个简易的模板。
最先建立一个word的模板
java工具
package com.lovo.utils.wordToPdf;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.poi.POIXMLDocument;
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;
/**
* 根据word模板生成新的wordjava工具
*
* @author zhiheng
*
*/
public class WorderToNewWordUtils {
/**
* 依据模板生成新word文档
* 分辨报表是必须更换或是必须插进,分辨逻辑性有$为更换,报表无$为插进
* @param inputUrl 模板储放详细地址
* @param outPutUrl 新文本文档储放详细地址
* @param textMap 必须更换的数据结合
* @param tableList 必须添加的报表信息内容结合
* @return 取得成功回到true,不成功回到false
*/
public static boolean changWord(String inputUrl, String outputUrl,
Map<String, String> textMap, List<String[]> tableList) {
//模板变换默认设置取得成功
boolean changeFlag = true;
try {
//获得docx分析对象
XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
//解析更换文字文段对象
WorderToNewWordUtils.changeText(document, textMap);
//分析更换报表对象
WorderToNewWordUtils.changeTable(document, textMap, tableList);
//生成新的word
File file = new File(outputUrl);
FileOutputStream stream = new FileOutputStream(file);
document.write(stream);
stream.close();
} catch (IOException e) {
e.printStackTrace();
changeFlag = false;
}
return changeFlag;
}
/**
* 更换文段文字
* @param document docx分析对象
* @param textMap 必须更换的数据结合
*/
public static void changeText(XWPFDocument document, Map<String, String> textMap){
//获得文段结合
List<XWPFParagraph> paragraphs = document.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
//分辨此文段情况下必须开展更换
String text = paragraph.getText();
if(checkText(text)){
List<XWPFRun> runs = paragraph.getRuns();
for (XWPFRun run : runs) {
//更换模板原先部位
run.setText(changeValue(run.toString(), textMap),0);
}
}
}
}
/**
* 更换报表对象方式
* @param document docx分析对象
* @param textMap 必须更换的数据结合
* @param tableList 必须添加的报表信息内容结合
*/
public static void changeTable(XWPFDocument document, Map<String, String> textMap,
List<String[]> tableList){
//获得报表目标结合
List<XWPFTable> tables = document.getTables();
for (int i = 0; i < tables.size(); i ) {
//只解决个数高于或等于2的报表,且不循环系统表头
XWPFTable table = tables.get(i);
if(table.getRows().size()>1){
//分辨报表是必须更换或是必须插进,分辨逻辑性有$为更换,报表无$为插进
if(checkText(table.getText())){
List<XWPFTableRow> rows = table.getRows();
//解析xml报表,并更换模版
eachTable(rows, textMap);
}else{
// System.out.println(\"插进\" table.getText());
insertTable(table, tableList);
}
}
}
}
/**
* 解析xml报表
* @param rows 表格行目标
* @param textMap 必须更换的数据结合
*/
public static void eachTable(List<XWPFTableRow> rows ,Map<String, String> textMap){
for (XWPFTableRow row : rows) {
List<XWPFTableCell> cells = row.getTableCells();
for (XWPFTableCell cell : cells) {
//分辨表格中是不是必须更换
if(checkText(cell.getText())){
List<XWPFParagraph> paragraphs = cell.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
List<XWPFRun> runs = paragraph.getRuns();
for (XWPFRun run : runs) {
run.setText(changeValue(run.toString(), textMap),0);
}
}
}
}
}
}
/**
* 为报表插进数据信息,个数不足加上新行
* @param table 必须插进数据信息的报表
* @param tableList 插进数据信息结合
*/
public static void insertTable(XWPFTable table, List<String[]> tableList){
//建立行,依据要添加的数据信息加上新行,不处理表头
for(int i = 1; i < tableList.size(); i ){
XWPFTableRow row =table.createRow();
}
//解析xml报表插进数据信息
List<XWPFTableRow> rows = table.getRows();
for(int i = 1; i < rows.size(); i ){
XWPFTableRow newRow = table.getRow(i);
List<XWPFTableCell> cells = newRow.getTableCells();
for(int j = 0; j < cells.size(); j ){
XWPFTableCell cell = cells.get(j);
cell.setText(tableList.get(i-1)[j]);
}
}
}
/**
* 分辨文字中情况下包括$
* @param text 文字
* @return 包括回到true,不包含返回false
*/
public static boolean checkText(String text){
boolean check = false;
if(text.indexOf(\"$\")!= -1){
check = true;
}
return check;
}
/**
* 配对传到信息内容聚集与模版
* @param value 模板必须更换的地区
* @param textMap 传到信息内容结合
* @return 模版必须更换地区信息内容结合相匹配值
*/
public static String changeValue(String value, Map<String, String> textMap){
Set<Entry<String, String>> textSets = textMap.entrySet();
for (Entry<String, String> textSet : textSets) {
//配对模版与更换值 文件格式${key}
String key = \"${\" textSet.getKey() \"}\";
if(value.indexOf(key)!= -1){
value = textSet.getValue();
}
}
//模版未配对到地区更换为空
if(checkText(value)){
value = \"\";
}
return value;
}
public static void main(String[] args) {
//模版文档详细地址
String inputUrl = \"C:\\Users\\zhihe\\Desktop\\demo\\001.docx\";
//新制造的模版文档
String outputUrl = \"C:\\Users\\zhihe\\Desktop\\demo\\test.docx\";
Map<String, String> testMap = new HashMap<String, String>();
testMap.put(\"name\", \"小亮\");
testMap.put(\"sex\", \"男\");
testMap.put(\"address\", \"科技园\");
testMap.put(\"phone\", \"88888888\");
List<String[]> testList = new ArrayList<String[]>();
testList.add(new String[]{\"1\",\"1AA\",\"1BB\",\"1CC\"});
testList.add(new String[]{\"2\",\"2AA\",\"2BB\",\"2CC\"});
testList.add(new String[]{\"3\",\"3AA\",\"3BB\",\"3CC\"});
testList.add(new String[]{\"4\",\"4AA\",\"4BB\",\"4CC\"});
WorderToNewWordUtils.changWord(inputUrl, outputUrl, testMap, testList);
}
}
检测
那么大家就保持了个简便的POI实际操作模版进行更换和插进的作用,原本还提前准备完成固定不动部位添加图片的作用,但是发觉这也是个巨坑,临时未完成其作用,等之后有时间再开展健全,此编码以docx文件格式开展演试实际操作
假如碰到poi载入例如{name}不可以鉴别为一个总体,可以应用word的域实际操作,假如不太清晰域的应用,可以如此实际操作,先往text文本文档中写好,例如{name},随后再全部拷贝到word中,不必一个一个在word中敲,要不然有可能不可能被poi鉴别为一个总体
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。