java操作xml導出word

java導出word[xml方式]

xml方式導出word優缺點:

優點:

         1、代碼量少,樣式、內容容易控制,打印不變形,符合office標準;

         2、支持Linux平臺,不要求安裝office;

         3、可以實現固定格式文檔輸出;

         4、支持添加圖片;

缺點:

         1、需要提前設計好word模板,把需要替換的地方用特殊標記標出來;

         2、若要在word中添加圖片,需要在設計模板時加入一張圖片進行佔位,然後手動編輯xml模板文檔;

1、XmlWord類的使用

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字符串

返回替換後的節點

 

本類目前僅能支持文本、圖片分次替換,未實現文本同圖片的同時替換。

 

模板:

    

 

導出後效果:

  

 

 

XmlWord類代碼:

 
 
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;
    }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章