如果遇到poi读取例如{name}不能识别为一个整体,可以使用word的域操作,如果不太清楚域的使用,可以这么操作,先在text文档中写好,例如{name},然后再整个复制到word中,不要一个一个在word中敲,不然有可能不会被poi识别为一个整体
poi是apache提供的可以操作word文档的第三方jar。poi能操作word是使用xwpfdocument对象。
xwpfdocument对象可以解析docx文件,在xwpfdocument对象通过输入流解析docx的时候,会获取到docx文档中的各种对象,例如表格,段落,图片等,通过操作xwpfdocument对象就可以修改模板内容xwpfdocument api结构org.apache.poi.xwpf.urmodel.xwpfdocumentxwpfdocument 提供write(outputstream stream)方法将修改后的对象重新写入xml并生成新的docx通过xwpfdocument 可以获得的docx中的各种对象
要具体操作通过xwpfdocument 可以获得的docx中的各种对象,我们离不开一个对象为xwpfrun对象,api结构
org.apache.poi.xwpf.urmodel.xwpfrun。其描述为:xwpfrun object defines a region of text with a common t 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:\urs\zhihe\desktop\demo@component("xwpruntest")public class xwpruntest {//模板文件地址private static string inputurl = "c:\urs\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 blocke.printstacktrace();}}}
1.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:\urs\zhihe\desktop\demo@component("xwpruntabletest")public class xwpruntabletest {//模板文件地址private static string inputurl = "c:\urs\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 blocke.printstacktrace();}}}
1.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:\urs\zhihe\desktop\demopublic class firstwordtest {//模板文件地址private static string inputurl = "c:\urs\zhihe\desktop\demo\001.docx";//新生产的模板文件private static string outputurl = "c:\urs\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.ttext("修改了的word");//生成新的wordfile file = new file(outputurl);fileoutputstream stream = new fileoutputstream(file);doucument.write(stream);stream.clo();} catch (ioexception e) {// todo auto-generated catch blocke.printstacktrace();}}public static void main(string[] args) {changeword(inputurl,outputurl);}}
1.docx"; //新生产的模板文件 private static string outputurl = "c:\urs\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.ttext("修改了的word"); //生成新的word file file = new file(outputurl); fileoutputstream stream = new fileoutputstream(file); doucument.write(stream); stream.clo(); } catch (ioexception e) { // todo auto-generated catch block e.printstacktrace(); } } public static void main(string[] args) { changeword(inputurl,outputurl); }}
测试
运行后生成新的word
但是在实际项目中并没有这么简单,模板文档中可能需要替换文本中的文字,也可能需要替换表格对象中的文字,或者在指定表格中插入数据,下面我们就仿照实际情况来做个简单的模板。
首先创建一个word的模板
工具类
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.t;import org.apache.poi.poixmldocument;import org.apache.poi.xwpf.urmodel.xwpfdocument;import org.apache.poi.xwpf.urmodel.xwpfparagraph;import org.apache.poi.xwpf.urmodel.xwpfrun;import org.apache.poi.xwpf.urmodel.xwpftable;import org.apache.poi.xwpf.urmodel.xwpftablecell;import org.apache.poi.xwpf.urmodel.xwpftablerow;/** * 通过word模板生成新的word工具类 * * @author zhiheng * */public class wordertonewwordutils { /** * 根据模板生成新word文档 * 判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入 * @param inputurl 模板存放地址 * @param outputurl 新文档存放地址 * @param textmap 需要替换的信息集合 * @param tablelist 需要插入的表格信息集合 * @return 成功返回true,失败返回fal */ 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.clo(); } catch (ioexception e) { e.printstacktrace(); changeflag = fal; } 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.ttext(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(); //遍历表格,并替换模板 eachtable(rows, textmap); }el{// system.out.println("插入"+table.gettext()); inrttable(table, tablelist); } } } } /** * 遍历表格 * @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.ttext(changevalue(run.tostring(), textmap),0); } } } } } } /** * 为表格插入数据,行数不够添加新行 * @param table 需要插入数据的表格 * @param tablelist 插入数据集合 */ public static void inrttable(xwpftable table, list<string[]> tablelist){ //创建行,根据需要插入的数据添加新行,不处理表头 for(int i = 1; i < tablelist.size(); i++){ xwpftablerow row =table.createrow(); } //遍历表格插入数据 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.ttext(tablelist.get(i-1)[j]); } } } /** * 判断文本中时候包含$ * @param text 文本 * @return 包含返回true,不包含返回fal */ public static boolean checktext(string text){ boolean check = fal; if(text.indexof("$")!= -1){ check = true; } return check; } /** * 匹配传入信息集合与模板 * @param value 模板需要替换的区域 * @param textmap 传入信息集合 * @return 模板需要替换区域信息集合对应值 */ public static string changevalue(string value, map<string, string> textmap){ t<entry<string, string>> textts = textmap.entr瑜伽能减肥吗yt(); for (entry<string, string> textt : textts) { //匹配模板与替换值 格式${key} string key = "${"+textt.getkey()+"}"; if(value.indexof(key)!= -1){ value = textt.getvalue(); } } //模撤诉申请书范本板未匹配到区域替换为空 if(checktext(value)){ value = ""; } return value; } public static void main(string[] args) { //模板文件地址 string inputurl = "c:\urs\zhihe\desktop\demopackage 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.t;import org.apache.poi.poixmldocument;import org.apache.poi.xwpf.urmodel.xwpfdocument;import org.apache.poi.xwpf.urmodel.xwpfparagraph;import org.apache.poi.xwpf.urmodel.xwpfrun;import org.apache.poi.xwpf.urmodel.xwpftable;import org.apache.poi.xwpf.urmodel.xwpftablecell;import org.apache.poi.xwpf.urmodel.xwpftablerow;/*** 通过word模板生成新的word工具类* * @author zhiheng* */public class wordertonewwordutils {/*** 根据模板生成新word文档* 判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入* @param inputurl 模板存放地址* @param outputurl 新文档存放地址* @param textmap 需要替换的信息集合* @param tablelist 需要插入的表格信息集合* @return 成功返回true,失败返回fal*/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);//生成新的wordfile file = new file(outputurl);fileoutputstream stream = new fileoutputstream(file);document.write(stream);stream.clo();} catch (ioexception e) {e.printstacktrace();changeflag = fal;}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.ttext(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.siz人弃我取人取我与e(); i++) {//只处理行数大于等于2的表格,且不循环表头xwpftable table = tables.get(i);if(table.getrows().size()>1){//判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入if(checktext(table.gettext())){list<xwpftablerow> rows = table.getrows();//遍历表格,并替换模板eachtable(rows, textmap);}el{// system.out.println("插入"+table.gettext());inrttable(table, tablelist);}}}}/*** 遍历表格* @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.ttext(changevalue(run.tostring(), textmap),0);}}}}}}/*** 为表格插入数据,行数不够添加新行* @param table 需要插入数据的表格* @param tablelist 插入数据集合*/public static void inrttable(xwpftable table, list<string[]> tablelist){//创建行,根据需要插入的数据添加新行,不处理表头for(int i = 1; i < tablelist.size(); i++){xwpftablerow row =table.createrow();}//遍历表格插入数据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.ttext(tablelist.get(i-1)[j]);}}}/*** 判断文本中时候包含$* @param text 文本* @return 包含返回true,不包含返回fal*/public static boolean checktext(string text){boolean check = fal;if(text.indexof("$")!= -1){check = true;}return check;}/*** 匹配传入信息集合与模板* @param value 模板需要替换的区域* @param textmap 传入信息集合* @return 模板需要替换区域信息集合对应值*/public static string changevalue(string value, map<string, string> textmap){t<entry<string, string>> textts = textmap.entryt();for (entry<string, string> textt : textts) {//匹配模板与替换值 格式${key}string key = "${"+textt.getkey()+"}";if(value.indexof(key)!= -1){value = textt.getvalue();}}//模板未匹配到区域替换为空if(checktext(value)){value = "";}return value;}public static void main(string[] args) {//模板文件地址string inputurl = "c:\urs\zhihe\desktop\demo\001.docx";//新生产的模板文件string outputurl = "c:\urs\zhihe\desktop\demo\test.docx";map<string, string> testmap = new hashmap<string, string>();testmap.put("name", "小明");testmap.put("x", "男");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);}}
1.docx"; //新生产的模板文件 string outputurl = "c:\urs\zhihe\desktop\demo\test.docx"; map<string, string> testmap = new hashmap<string, string>(); testmap.put("name", "小明"); testmap.put("x", "男"); 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.a减肥最好办法dd(new string[]{"4","4aa","4bb","4cc"}); wordertonewwordutils.changword(inputurl, outputurl, testmap, testlist); }}
测试
这么我们就实现了个简单的poi操作模板完成替换和插入的功能,本来还准备实现固定位置插入图片的功能,不过发现这是个巨坑,暂时未实现其功能,等以后有空再进行完善,此代码以docx格式进行演示操作
如果遇到poi读取例如{name}不能识别为一个整体,可以使用word的域操作,如果不太清楚域的使用,可以这么操作,先在text文档中写好,例如{name},然后再整个复制到word中,不要一个一个在word中敲,不然有可能不会被poi识别为一个整体
本文发布于:2023-04-05 04:54:54,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/c94cf2c9eb37e22b4c4ddb2f52d5d1e0.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:easypoi导出word换行(easypoi导出数字类型).doc
本文 PDF 下载地址:easypoi导出word换行(easypoi导出数字类型).pdf
留言与评论(共有 0 条评论) |