xml方式导出word优缺点:
优点:
1、代码量少,样式、内容容易控制,打印不变形,符合office标准;
2、支持Linux平台,不要求安装office;
3、可以实现固定格式文档输出;
4、支持添加图片;
缺点:
1、需要提前设计好word模板,把需要替换的地方用特殊标记标出来;
2、若要在word中添加图片,需要在设计模板时加入一张图片进行占位,然后手动编辑xml模板文档;
1、XmlWord类的使用(使用org.w3c.dom操作XML)
XmlWord类源码:XmlWord.txt
示例代码所用模板:2.xml
【注】:创建模板的office需2003及以上版本。
使用步骤:
1、创建一个需要导出word模板;
2、创建一个XmlWord对象;
3、若模板标记有多个,存储至list中;存储替换值;
4、生成word文档;
[示例代码]:
XmlWordtest=newXmlWord();
//1、载入模板
Documentdoc=test.LoadXml("2.xml");
//2、设置标记,tagList中存放的标记要同模板中的标记一致;
List<String>tagList=newArrayList<String>();
tagList.add("${test_name}");
tagList.add("${test_no}");
//3、设置填充标记的值,dataList中存放数据顺序与tagList存放标记顺序一致;
List<String>dataList=newArrayList<String>();
dataList.add("----用例名");
dataList.add("----用例编号");
//4、将标记和标记值存入dataMap
test.setData(tagList,dataList);
//5、替换值
/*添加图片*/
test.replacePic(doc.getDocumentElement(),"${img}","8.jpg",imgStr);
test.replaceTagContext(doc.getDocumentElement());
//6、写入文档
test.doc2DocFile(doc,"xmlword.doc");
2、特殊说明
1、word模板制作:
使用office2003及以上版本写一个需要导出的word模板,然后编辑文档的样式,将需要动态填充的内容,使用特殊标记替换,如实例代码中的标记(${test_name}),最后将编辑后的word文档另存为为“Word2003XML文档(*.xml)”格式,将模板放置在工程下。
2、添加图片:
如果需要在word中添加图片,在第一步制作模板时,加入一张图片占位,然后打开xml文档,可以看到如下的一片base64编码后的代码:
<w:binDataw:name="wordml://03001.png"xml:space="preserve">iVBO……CC</w:binData>
只要将base64的代码替换成例如:${p_w_picpath},如下:
<w:binDataw:name="wordml://03001.png"xml:space="preserve">${p_w_picpath}</w:binData>
这里要注意“>${p_w_picpath}<”这尖括号中间不能加任何其他的诸如空格,tab,换行等符号,否则导出的word将会出错。
3、XmlWord类说明
Properties:
变量 | 说明 |
Map<String,String>dataMap | 用于当模板中有多个标记时存放标记值及替换数据。 |
Methods:
方法 | 参数 | 返回值 |
LoadXml(Stringfilename):Document 载入一个xml文档 | filename:模板路径 | 成功返回Document对象; 失败返回null |
getImageStr(StringimgFile):String 图片转码 | ImgFile:图片全路径名 | 返回图片base64字符串 |
doc2DocFile(Documentdocument,Stringfilename):boolean 将Document对象保存为一个Doc文件 | filename:保存的文件名 document:需要保存的Document对象 | true:保存成功 false:保存失败 |
replaceTagContext(Elementelement,Stringtag,Stringdata):Element 替换标识内容:单个标记(仅用于替换文本) | element:要填充内容的节点 tag:模板中标记 data:数据 | 返回替换后的节点 |
replaceTagContext(Elementelement):Element 替换标识内容:多个标记,调用此方法前,先调用setData方法(仅用于替换文本) | element:要替换内容的节点 | 返回替换后的节点 |
replacePic(Objectelement,Stringtag,StringimgName,StringimgStr):Element 添加图片,此方法仅适用于单张图片的添加,多图添加可参考该方法源码 | element:要替换内容的节点 tag:模板中图片标记 imgName:图片名称,若word中有多张图,图片名必须唯一 imgStr:图片转码后的base64字符串 | 返回替换后的节点 |
本类目前仅能支持文本、图片分次替换,未实现文本同图片的同时替换。
模板:
导出后效果:
XmlWord类代码:
packagecom.hxh.test;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileNotFoundException;importjava.io.FileOutputStream;importjava.io.IOException;importjava.io.InputStream;importjava.util.ArrayList;importjava.util.Date;importjava.util.HashMap;importjava.util.Iterator;importjava.util.List;importjava.util.Map;importjava.util.Set;importjavax.xml.parsers.DocumentBuilder;importjavax.xml.parsers.DocumentBuilderFactory;importjavax.xml.transform.Transformer;importjavax.xml.transform.TransformerFactory;importjavax.xml.transform.dom.DOMSource;importjavax.xml.transform.stream.StreamResult;importorg.w3c.dom.Document;importorg.w3c.dom.Element;importorg.w3c.dom.NodeList;importsun.misc.BASE64Encoder;publicclassXmlWord{private Map<String,String> dataMap = new HashMap<String,String>();public Map<String, String>getDataMap(){returndataMap;}publicvoid setDataMap(Map<String, String>dataMap){this.dataMap =dataMap;}/***设置标识值*@paramtagList标识*@paramdataList数据*@paramdataMap*/publicvoid setData(List<String> tagList,List<String>dataList){Iterator<String> it1 =tagList.iterator();Iterator<String> it2 =dataList.iterator();while(it1.hasNext()){this.dataMap.put(it1.next(),it2.next());}}/***载入一个xml文档*@paramfilename文件路径*@return成功返回Document对象,失败返回null*/publicDocumentLoadXml(Stringfilename){Documentdoc= null;try{DocumentBuilderFactoryfactory=DocumentBuilderFactory.newInstance();DocumentBuilderbuilder=factory.newDocumentBuilder();doc= (Document) builder.parse(newFile(filename));}catch(Exceptione){System.out.println("载入xml文件时出错");e.printStackTrace();}returndoc;}/***图片转码*@return返回图片base64字符串*@throwsException*/publicStringgetImageStr(StringimgFile){InputStreamin= null;BASE64Encoderencoder= null;byte[] data = null;try{in= newFileInputStream(imgFile);}catch(FileNotFoundExceptione){System.out.println("文件没找到!");e.printStackTrace();}try{data= newbyte[in.available()];in.read(data);in.close();}catch(IOExceptione){e.printStackTrace();}encoder= newBASE64Encoder();returnencoder.encode(data);}/***doc2XmlFile*将Document对象保存为一个xml文件*@returntrue:保存成功flase:失败*@paramfilename保存的文件名*@paramdocument需要保存的document对象*/publicbooleandoc2XmlFile(Documentdocument,Stringfilename){boolean flag = true;try{TransformerFactorytransFactory=TransformerFactory.newInstance();Transformertransformer=transFactory.newTransformer();DOMSourcesource=newDOMSource();source.setNode(document);StreamResultresult=newStreamResult();FileOutputStreamfileOutputStream= newFileOutputStream(filename);result.setOutputStream(fileOutputStream);transformer.transform(source,result);fileOutputStream.close();}catch(Exceptionex){flag= false;ex.printStackTrace();}returnflag;}/***替换标识内容:单个文本标记*@paramelement要替换内容的节点*@paramtag标识名称*@paramdata替换参数*@return返回替换后的节点*@throwsException*/publicElementreplaceTagContext(Objectelement,Stringtag,Stringdata){ElementxElement= null;xElement=(Element)element;NodeListtElements= xElement.getElementsByTagName("w:t");//w:t标签组for(int i=0; i<tElements.getLength(); i++){ElementtElement=(Element)tElements.item(i);if(tElement.getTextContent().equals(tag)){tElement.setTextContent(data);}}returnxElement;}/***替换标识内容:多个文本标记*@paramelement要替换内容的节点*@return返回替换后的节点*@throwsException*/publicElementreplaceTagContext(Elementelement){ElementxElement=element;NodeListtElements= xElement.getElementsByTagName("w:t");//w:t标签组 Set<String> dataSet = this.dataMap.keySet();Iterator<String> it =dataSet.iterator();while(it.hasNext()){Stringtag=it.next();Stringdata=dataMap.get(tag);for(int i=0; i<tElements.getLength(); i++){ElementtElement=(Element)tElements.item(i);if(tElement.getTextContent().equals(tag)){tElement.setTextContent(data);}}}returnxElement;}/***添加图片*@paramelement需要替换内容的节点*@paramtag标识名称*@paramimgName图片名称,若word中有多张图,图片名必须唯一*@paramimgStr图片转码后的base64字符串*@return返回替换后的节点*/publicElementreplacePic(Elementelement,Stringtag,StringimgName,StringimgFile){ElementxElement=element;NodeListtElements= xElement.getElementsByTagName("w:binData");//w:t标签组pkg:binaryData String wName = "wordml://"+imgName;for(int i=0; i<tElements.getLength(); i++){ElementpicElement=(Element)tElements.item(i);if(picElement.getTextContent().equals(tag)){picElement.setTextContent(this.getImageStr(imgFile));/*图片编码*/picElement.setAttribute("w:name",wName);//设置名字 Element p_w_picpathdataElement = (Element) xElement.getElementsByTagName("v:p_w_picpathdata").item(i);p_w_picpathdataElement.setAttribute("src",wName);}}returnxElement;}/***插入图片*@paramparentElement图片添加至何处*@paramimgFile图片路径*@paramisnewLine是否换行*@return返回添加图片节点后的节点*/public Element addPic(Element parentElement,String imgFile,booleanisnewLine){Documentparent=parentElement.getOwnerDocument();Elementp= null;Elementpict= null;ElementbinData= null;Elementshape= null;Elementp_w_picpathdata= null;Stringsrc= "wordml://" + newDate().getTime();if(isnewLine){p= parent.createElement("w:p");}pict= parent.createElement("w:pict");binData= parent.createElement("w:binData");binData.setAttribute("w:name",src);binData.setAttribute("xml:space", "preserve");binData.setTextContent(this.getImageStr(imgFile));shape= parent.createElement("v:shape");p_w_picpathdata= parent.createElement("v:p_w_picpathdata");p_w_picpathdata.setAttribute("src",src);//构造图片节点shape.appendChild(p_w_picpathdata);pict.appendChild(binData);pict.appendChild(shape);if(isnewLine){p.appendChild(pict);parentElement.appendChild(p);}else{parentElement.appendChild(pict);}returnparentElement;}/***插入段落*@paramparentElement待添加段落的节点*@paramdata待插入数据*@return*/publicElementaddParagraph(ElementparentElement,Stringdata){Documentparent=parentElement.getOwnerDocument();Elementp= null;Elementr= null;Elementt= null;p= parent.createElement("w:p");r= parent.createElement("w:r");t= parent.createElement("w:t");t.setTextContent(data);//构造图片节点r.appendChild(t);p.appendChild(r);parentElement.appendChild(p);returnparentElement;}}
转载于:https://blog.51cto.com/5711079/1307160