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文档;

[示例代码]:

XmlWord test = new XmlWord();

//1、载入模板

Document doc = test.LoadXml("2.xml");

//2、设置标记,tagList中存放的标记要同模板中的标记一致;

List<String> tagList = new ArrayList<String>();

tagList.add("${test_name}");

tagList.add("${test_no}");

//3、设置填充标记的值,dataList中存放数据顺序与tagList存放标记顺序一致;

List<String> dataList = new ArrayList<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模板制作:

使用office 2003及以上版本写一个需要导出的word模板,然后编辑文档的样式,将需要动态填充的内容,使用特殊标记替换,如实例代码中的标记(${test_name}),最后将编辑后的word文档另存为为“Word 2003 XML 文档(*.xml)”格式,将模板放置在工程下。

2、添加图片:

如果需要在word中添加图片,在第一步制作模板时,加入一张图片占位,然后打开xml文档,可以看到如下的一片base64编码后的代码:

<w:binData w:name="wordml://03001.png" xml:space="preserve">iVBO……CC</w:binData>

只要将base64的代码替换成例如:${image},如下:

<w:binData w:name="wordml://03001.png" xml:space="preserve">${image}</w:binData>

这里要注意“>${image}<”这尖括号中间不能加任何其他的诸如空格,tab,换行等符号,否则导出的word将会出错。

3、XmlWord类说明

Properties:

变量

说明

Map<String,String> dataMap

用于当模板中有多个标记时存放标记值及替换数据。

Methods:

方法

参数

返回值

LoadXml(String filename):Document

载入一个xml文档

filename:模板路径

成功返回Document对象;

失败返回null

getImageStr(String imgFile):String

图片转码

ImgFile:图片全路径名

返回图片base64字符串

doc2DocFile(Document document,String   filename):boolean

将Document对象保存为一个Doc文件

filename:保存的文件名

document:需要保存的Document对象

true:保存成功

false:保存失败

replaceTagContext(Element element,String tag,String data):Element

替换标识内容:单个标记(仅用于替换文本)

element:要填充内容的节点

tag:模板中标记

data:数据

返回替换后的节点

replaceTagContext(Element element):Element

替换标识内容:多个标记,调用此方法前,先调用setData方法(仅用于替换文本)

element:要替换内容的节点

返回替换后的节点

replacePic(Object element,String   tag,String imgName,String imgStr):Element

添加图片,此方法仅适用于单张图片的添加,多图添加可参考该方法源码

element:要替换内容的节点

tag:模板中图片标记

imgName:图片名称,若word中有多张图,图片名必须唯一

imgStr:图片转码后的base64字符串

返回替换后的节点

本类目前仅能支持文本、图片分次替换,未实现文本同图片的同时替换。

模板:

    

导出后效果:

  

package com.hxh.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import sun.misc.BASE64Encoder;

public class XmlWord {
    
    private Map<String,String> dataMap = new HashMap<String,String>();
    public Map<String, String> getDataMap() {
        return dataMap;
    }

public void setDataMap(Map<String, String> dataMap) {
        this.dataMap = dataMap;
    }
    
    /**
     * 设置标识值
     * @param tagList 标识
     * @param dataList 数据
     * @param dataMap
     */
    public void 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文档
     * @param filename 文件路径
     * @return 成功返回Document对象,失败返回null
     */
    public Document LoadXml(String filename){
        
        Document doc = null;
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
            DocumentBuilder builder = factory.newDocumentBuilder();
            doc = (Document) builder.parse(new File(filename));
        } catch (Exception e) {
            System.out.println("载入xml文件时出错");
            e.printStackTrace();
        }
        return doc;
    }
    
    /**
     * 图片转码
     * @return 返回图片base64字符串
     * @throws Exception
     */
    public String getImageStr(String imgFile){
        InputStream in = null;
        BASE64Encoder encoder = null;
        byte[] data = null;
        try {
            in = new FileInputStream(imgFile);
        } catch (FileNotFoundException e) {
            System.out.println("文件没找到!");
            e.printStackTrace();
        }
        try {
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        encoder = new BASE64Encoder();
        return encoder.encode(data);
    }
    /** 
     * doc2XmlFile 
     * 将Document对象保存为一个xml文件 
     * @return true:保存成功  flase:失败 
     * @param filename 保存的文件名 
     * @param document 需要保存的document对象 
     */ 
    public boolean doc2XmlFile(Document document,String filename) 
    { 
       boolean flag = true; 
       try{
           TransformerFactory transFactory = TransformerFactory.newInstance(); 
              Transformer transformer = transFactory.newTransformer();
           DOMSource source=new DOMSource();
           source.setNode(document);
           StreamResult result=new StreamResult();
           FileOutputStream fileOutputStream = new FileOutputStream(filename); 
           result.setOutputStream(fileOutputStream);
           transformer.transform(source, result);
           fileOutputStream.close();          
       }catch(Exception ex){ 
           flag = false; 
           ex.printStackTrace(); 
       } 
       return flag;       
    }
    
    /**
     * 替换标识内容:单个文本标记
     * @param element 要替换内容的节点
     * @param tag 标识名称
     * @param data 替换参数
     * @return 返回替换后的节点
     * @throws Exception
     */
    public Element replaceTagContext(Object  element,String tag,String data){
        Element xElement = null;
        xElement = (Element) element;
        NodeList tElements = xElement.getElementsByTagName("w:t");//w:t标签组 
        for(int i=0; i<tElements.getLength(); i++){
            Element tElement = (Element)tElements.item(i);
            if(tElement.getTextContent().equals(tag)){
                 tElement.setTextContent(data);
             }
        }
        return xElement;
    }
    
    /**
     * 替换标识内容:多个文本标记
     * @param element 要替换内容的节点
     * @return 返回替换后的节点
     * @throws Exception
     */
    public Element replaceTagContext(Element  element){
        Element xElement = element;
        NodeList tElements = xElement.getElementsByTagName("w:t");//w:t标签组 
        Set<String> dataSet = this.dataMap.keySet();
        Iterator<String> it = dataSet.iterator();
        while(it.hasNext()){
            String tag = it.next();
            String data = dataMap.get(tag);
            for(int i=0; i<tElements.getLength(); i++){
                Element tElement = (Element)tElements.item(i);
                if(tElement.getTextContent().equals(tag)){
                     tElement.setTextContent(data);
                 }
            }
        }
        return xElement;
    }
    
    /**
     * 添加图片
     * @param element 需要替换内容的节点 
     * @param tag 标识名称
     * @param imgName 图片名称,若word中有多张图,图片名必须唯一
     * @param imgStr 图片转码后的base64字符串
     * @return 返回替换后的节点
     */
    public Element replacePic(Element element,String tag,String imgName,String imgFile){
        Element xElement = element;
        NodeList tElements = xElement.getElementsByTagName("w:binData");//w:t标签组  pkg:binaryData
        String wName = "wordml://"+imgName;
        for(int i=0; i<tElements.getLength(); i++){
            Element picElement = (Element)tElements.item(i);
            if(picElement.getTextContent().equals(tag)){
                 picElement.setTextContent(this.getImageStr(imgFile));/*图片编码*/
                 picElement.setAttribute("w:name",wName);//设置名字
                 Element imagedataElement = (Element) xElement.getElementsByTagName("v:imagedata").item(i);
                 imagedataElement.setAttribute("src",wName);
             }
        }
        return xElement;
    }
    
    
    /**
     * 插入图片
     * @param parentElement 图片添加至何处
     * @param imgFile 图片路径
     * @param isnewLine 是否换行
     * @return 返回添加图片节点后的节点
     */
    public Element addPic(Element parentElement,String imgFile,boolean isnewLine){
        Document parent = parentElement.getOwnerDocument();
        Element p = null;
        Element pict = null;
        Element binData = null;
        Element shape = null;
        Element imagedata = null;
        String src = "wordml://" + new Date().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");
        imagedata = parent.createElement("v:imagedata");
        imagedata.setAttribute("src", src);
        //构造图片节点
        shape.appendChild(imagedata);
        pict.appendChild(binData);
        pict.appendChild(shape);
        if(isnewLine){
            p.appendChild(pict);
            parentElement.appendChild(p);
        }else{
            parentElement.appendChild(pict);
        }
        return parentElement;
    }
    
    /**
     * 插入段落
     * @param parentElement 待添加段落的节点
     * @param data 待插入数据
     * @return
     */
    public Element addParagraph(Element parentElement,String data){
        Document parent = parentElement.getOwnerDocument();
        Element p = null;
        Element r = null;
        Element t = 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);
        return parentElement;
    }

}

xml方式导出word优缺点:相关推荐

  1. OpenXML方式导出word

    最近开发碰到一个导出word问题,导出内容涉及富文本.尝试了使用word模版书签插值的方式,不过不支持富文本:又尝试了Aspose.Words插件,的确好用,对富文本支持也比较好,奈何这玩意是收费的, ...

  2. java 导出word xml格式_关于Java导出Word文件

    做个很多个项目里基本上都涉及了word.Excel导入导出,虽然其中的要求有些小差异,不过总的方向上变化不大,所以做一些总结: 一).利用freemarker,制作xml模版导出word Xml模版部 ...

  3. java填充wordxml格式,java xml转成word文档格式

    xml格式如何转换成doc格式文件 通过jodconveter来实现转化(http://www.artofsolving.com/opensource/jodconverter). 这种方式实现起来比 ...

  4. JAVA导出Word文档工具EasyWord

    介绍 基于Apache poi封装,在上层做了模型转换的封装,让使用者更加简单方便 只支持docx的导出,不支持doc 下面废话少说 让我们以最快的方式学会用java导出word文档 组件依赖 依赖 ...

  5. FreeMaker+Xml导出word(含图片)

    最近在做一个简报导出的功能,要求导出word格式,上网找了很多资料,一开始选择了poi后来发现poi只能导出简单的word数据,后来偶然发现了通过FreeMaker模板生成word,说实话,还挺好用的 ...

  6. java 桥 word_java导出word的6种方式(转发)

    最近做的项目,需要将一些信息导出到word中.在网上找了好多解决方案,现在将这几天的总结分享一下. 目前来看,java导出word大致有6种解决方案: 1:Jacob是Java-COM Bridge的 ...

  7. java导出word的几种方式

    目前来看,java导出word大致有6种解决方案: 1:Jacob是Java-COM Bridge的缩写,它在Java与微软的COM组件之间构建一座桥梁.使用Jacob自带的DLL动态链接库,并通过J ...

  8. java导出word纸张方向_java导出word的几种方式

    目前来看,java导出word大致有6种解决方案: 1:Jacob是Java-COM Bridge的缩写,它在Java与微软的COM组件之间构建一座桥梁.使用Jacob自带的DLL动态链接库,并通过J ...

  9. 基于freemarker(mht)方式导出带图片的富文本word

    需求 批量将包含富文本的页面(含图片)导出为word的压缩包,并将每个页面的附件一同下载,下载的文件夹路径格式我就不展示了,具体页面如下 本次导出采用基于freemarker的word导出.大体上都是 ...

最新文章

  1. KingDZ 变菜鸟,每日一个C#小实例之---百叶窗图片展示
  2. 3、MySQL的数据类型介绍
  3. 创建表空间时ora-01119和ora-27040的处理
  4. Prewitt滤波器的实现,对比Prewitt滤波器和Sobel滤波器提取图像边缘的效果
  5. 「离散数学」【试卷一试题与答案】[推荐学习]
  6. winscp是什么软件_避免使用绿色版破解版和不更新的FTP软件
  7. PHP内容管理系统详细制作步骤
  8. Visual Studio中输入英文会在字母之间自动增加空格
  9. Web前端低代码介绍的ppt大纲
  10. java hql查询_Spring 中常用的hql查询方法(getHibernateTemplate())(转)
  11. 珠心算测验(2014NOIP)
  12. 如何制作视频画中画?制作画中画视频的方法
  13. 地图附近名片流量主小程序开发
  14. IBM Guardium
  15. 手机耗电统计app_Android O 新特性:精确统计 APP 电量消耗
  16. 怎么办理软件产品登记测试报告,软件产品登记有什么作用?
  17. POI操作Word文档工具
  18. 这么火的录音转文字软件,你用过吗?
  19. 让DIV标签中的p标签内容水平垂直居中
  20. 可用于SDR的C语言纠错编码通用算法收集(3)-卷积码与Viterbi译码

热门文章

  1. mysql编译安装指定端口_在CentOS7系统上编译安装MySQL 5.7.13步骤详解
  2. python中怎样划分时间段_早中晚时间段是怎样划分的?
  3. 一本书的推荐序——写在《思考的乐趣》即将上市之际
  4. 直播连麦实现的三种方法
  5. CCF 难题汇总(2013-2019 持续更新)
  6. 中点画线法(计算机图形学)
  7. 【String字符串分割以及字符串截取】
  8. 中间件 BES 连接池的配置和问题诊断方法
  9. 【全球品牌】圣经中人物的名字有哪些?
  10. 【Educoder作业】绘制炸弹轨迹 I——绘制一个坐标点