Java:利用XML生成Word文档

VN:F [1.9.10_1130]
Rating: 0.0/5 (0 votes cast)

Word 2003后提供了一种xml的文档格式。可以利用这一点方便的生成doc文档

Word 2007更完全使用xml与数据压缩包的方式存储,使得用类似的方法处理附件也变为可能。

相关demo下载 doc-creator

概述

实现步骤如下:

  1. 定义Word文档样式,存为xml文档。
  2. 定义数据xml格式,生成样本数据。
  3. 修改word文档样式xml文件,制作xsl模板文件。
  4. 编程实现:数据->xml数据->模板转换->doc文档

创建模板

打开Word文档,另存为:Word 2003 xml格式。

使用xsl编辑器 (如 Stylus Studio)或手工编辑,创建XSL模板 。

   

   

相关XSL问题可以参考 http://www.w3schools.com/xsl/

利用dom4j处理相关xml操作

下面是一些基础实现方法

    /*
     * (non-Javadoc)
     *
     * @see cn.ccb.sarm.bizprocess.assetdeal.exam.approve.bizservice.IWfConferenceBS#writeXML(java.io.OutputStream,
     *      cn.ccb.sarm.bizprocess.assetdeal.exam.approve.common.bo.TaskVO,
     *      java.util.List, cn.ccb.sarm.common.model.bo.WfConferenceBO,
     *      cn.ccb.sarm.common.model.bo.WfConfBpBO)
     */
    public void writeXML(OutputStream output, TaskVO task, List opinionList, WfConferenceBO conf,
            WfConfBpBO confBP) throws IOException, IllegalAccessException,
            InvocationTargetException, NoSuchMethodException {
        Document doc = DocumentHelper.createDocument();
        Element root = doc.addElement("conference");
        Element taskNode = root.addElement("task");
        addBeanProp(task, taskNode);
        Element confNode = root.addElement("conferenceInfo");
        addBeanProp(conf, confNode);
        Element confBpNode = root.addElement("confBPInfo");
        addBeanProp(confBP, confBpNode);
        Element approveNode = root.addElement("approvers");

        addListMapEntry(opinionList, approveNode);

        XMLWriter writer = new XMLWriter(output);
        writer.write(doc);

    }

    /**
     * 转换list对象为多个元素
     *
     * @param list
     *            对象list
     * @param node
     *            父节点
     */
    private void addListMapEntry(List list, Element node) {
        Iterator it = list.iterator();
        while (it.hasNext()) {
            Map map = (Map) it.next();
            Element approveNode = node.addElement("approver");
            addMapEntry(map, approveNode);
        }
    }

    /**
     * 转换bean为xml
     *
     * @param bean
     *            对象bean
     * @param node
     *            父节点
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     * @throws NoSuchMethodException
     */
    private void addBeanProp(Object bean, Element node) throws IllegalAccessException,
            InvocationTargetException, NoSuchMethodException {
        Map propMap = BeanUtils.describe(bean);
        addMapEntry(propMap, node);
    }

    /**
     * 转换map对象为xml
     *
     * @param map
     *            数据对象
     * @param node
     *            父节点
     */
    private void addMapEntry(Map map, Element node) {
        Set entrySet = map.entrySet();
        Iterator it = entrySet.iterator();
        while (it.hasNext()) {
            Map.Entry e = (Entry) it.next();
            node.addElement(e.getKey().toString()).addText(
                    (e.getValue() == null ? "" : e.getValue().toString()));
        }
    }

    /*
     * (non-Javadoc)
     *
     * @see cn.ccb.sarm.bizprocess.assetdeal.exam.approve.bizservice.IWfConferenceBS#transformDocument(java.io.OutputStream,
     *      java.io.FileInputStream, java.io.FileInputStream)
     */
    public void transformDocument(OutputStream out, InputStream data, InputStream template)
            throws TransformerException {
        TransformerFactory factory = TransformerFactory.newInstance();
        Transformer transform = factory.newTransformer(new StreamSource(template));

        Result result = new StreamResult(out);
        transform.transform(new StreamSource(data), result);
    }

测试代码

    public void testWriteXML() throws Exception {
        IWfConferenceBS conferenceBS = new WfConferenceBS();
        TaskVO task = new TaskVO();
        task.setBizTypeName("测试业务类型");
        List opinionList = new ArrayList();
        Map m = new HashMap();
        m.put("userName", "testUser");
        m.put("userConfRole", "testUserRole");
        m.put("approverOpinion", "approverOpinion");
        m.put("lastChangeTime", "time");
        opinionList.add(m);
        WfConferenceBO conf = new WfConferenceBO();
        conf.setConfPlace("place");
        WfConfBpBO confBP = new WfConfBpBO();
        confBP.setConfResult("testResult");
        confBP.setConfOpinion("confOpinion");
        File tempOutputFile = File.createTempFile("specialApproveTemp", ".xml");
        OutputStream output = new FileOutputStream(tempOutputFile);
        conferenceBS.writeXML(output, task, opinionList, conf, confBP);
        output.flush();
        output.close();

        OutputStream out = new FileOutputStream(File.createTempFile("specialApproveTemp", ".doc"));
        File template = ResourceUtils
                .getFile("classpath:cn/ccb/clpm/wf/common/specialApproveTemplate.xsl");
        conferenceBS.transformDocument(out, new FileInputStream(tempOutputFile),
                new FileInputStream(template));
        output.flush();
        output.close();

    }

您可能有兴趣的文章:

VN:F [1.9.10_1130]
Rating: 0.0/5 (0 votes cast)
Creative Commons License
This work, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.

11 Comments

  • haven
    2009/02/03 - 3:53 PM | Permalink

    您好。我的现在的项目正好需要用XML生产word的,遇到了不懂的地方,能否将您这篇文章的dome源码发一份给我参考一下。不胜感激,我的邮箱liulh-1@163.com.期待 您的回信

    VA:F [1.9.10_1130]
    Rating: 0 (from 0 votes)
  • gongfs
    2009/02/12 - 1:47 PM | Permalink

    能否将您这篇文章的dome源码发一份给我参考一下。非常感谢你!我的邮箱gfswsry@163.com.

    VA:F [1.9.10_1130]
    Rating: 0 (from 0 votes)
  • lion
    2009/02/25 - 5:37 PM | Permalink

    您好,我也希望要一份,谢谢。My mail: lhblion@126.com

    VA:F [1.9.10_1130]
    Rating: 0 (from 0 votes)
  • 雪儿
    2009/06/15 - 1:06 PM | Permalink

    哈哈~~ 我来冒泡~~

    VA:F [1.9.10_1130]
    Rating: 0 (from 0 votes)
  • 2009/06/15 - 1:30 PM | Permalink

    @雪儿: 干嘛挑这篇来冒泡……

    VN:F [1.9.10_1130]
    Rating: 0 (from 0 votes)
  • Jack
    2009/07/17 - 3:11 PM | Permalink

    下载的资源不存在了。。。能发我一份吗?不胜感激!!

    VA:F [1.9.10_1130]
    Rating: 0 (from 0 votes)
  • 2009/07/17 - 10:01 PM | Permalink

    @Jack: 很乐意帮忙,但是说实话,单纯操作Word,这个实现并不好,请参考新版本的POI或者Velocity或者Freemarker项目。

    VN:F [1.9.10_1130]
    Rating: 0 (from 0 votes)
  • 袖舞清风
    2009/10/03 - 11:10 AM | Permalink

    你好,我最近用这种方法做数据的导出,想借大哥的这种方法用一下,我的邮件是erenzone@gmail.com,请传一份给我,谢谢!

    VA:F [1.9.10_1130]
    Rating: 0 (from 0 votes)
  • 2009/02/05 - 11:24 PM | Permalink

    邮件已发送,请查收

    VA:F [1.9.10_1130]
    Rating: 0 (from 0 votes)
  • 2009/02/25 - 11:59 PM | Permalink

    请仔细看原文,有下载

    VA:F [1.9.10_1130]
    Rating: 0 (from 0 votes)
  • kgj
    2009/05/31 - 5:31 PM | Permalink

    我也想要一份.急..给我发一份吧

    VA:F [1.9.10_1130]
    Rating: 0 (from 0 votes)
  • Leave a Reply

    Your email address will not be published. Required fields are marked *

    *

    You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>