鍍金池/ 問(wèn)答/Java  網(wǎng)絡(luò)安全  Office/ java如何將xml類型的word文檔轉(zhuǎn)換為word類型的文檔

java如何將xml類型的word文檔轉(zhuǎn)換為word類型的文檔

我的需求是這樣的:
word文檔類型是xml,用文本編輯器打開(kāi)看到以下代碼(我只拷貝了頭部部分代碼)
java如何能把它轉(zhuǎn)換為word類型的doc文檔,Apache的poi好像只能把word文檔轉(zhuǎn)換成xml、html等格式的,但不能反過(guò)來(lái)轉(zhuǎn)。請(qǐng)問(wèn)有沒(méi)有解決過(guò)這種需求的朋友,先謝謝了!

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?mso-application progid="Word.Document"?>
<pkg:package xmlns:pkg="http://schemas.microsoft.com/office/2006/xmlPackage">
    <pkg:part pkg:name="/_rels/.rels" pkg:contentType="application/vnd.openxmlformats-package.relationships+xml">
        <pkg:xmlData>
            <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
                <Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/>
                <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>
                <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>
                <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties" Target="docProps/custom.xml"/>
            </Relationships>
        </pkg:xmlData>
    </pkg:part>
回答
編輯回答
故人嘆

@smilesnake 首先感謝分享代碼,可能是我的問(wèn)題,沒(méi)有把問(wèn)題描述清楚,我目前就是按照你的思路來(lái)做的,但問(wèn)題是最后給用戶生成的這個(gè)doc文檔是xml類型的(另存為的時(shí)候能夠看到)并且用戶打開(kāi)編輯后再去另存的時(shí)候就變成了xml為后綴的文檔了,導(dǎo)致后面打不開(kāi),所以我的問(wèn)題是如何能生成word類型的文檔

2017年4月28日 02:56
編輯回答
詆毀你

大致的思路是先用office2003或者2007編輯好word的樣式,然后另存為xml,將xml翻譯為FreeMarker模板,最后用java來(lái)解析FreeMarker模板并輸出Doc。經(jīng)測(cè)試這樣方式生成的word文檔完全符合office標(biāo)準(zhǔn),樣式、內(nèi)容控制非常便利,打印也不會(huì)變形,生成的文檔和office中編輯文檔完全一樣。
用xml做導(dǎo)出方案。

先創(chuàng)建一個(gè)word文檔,按照需求在word中填好一個(gè)模板,然后把對(duì)應(yīng)的數(shù)據(jù)換成變量${},然后將文檔保存為xml文檔格式,使用文檔編輯器打開(kāi)這個(gè)xml格式的文檔,去掉多余的xml符號(hào),使用Freemarker讀取這個(gè)文檔然后替換掉變量,輸出word文檔即可

需要freemarker jar包

/**

  • Project Name:exam-services
  • File Name:DownloadService.java
  • Package Name:com.wt.service.download
  • Date:2016年9月28日下午4:44:37
  • Copyright (c) 2016, chenzhou1025@126.com All Rights Reserved.

*/

package com.wt.service.download;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.http.HttpServletResponse;

import net.paoding.rose.web.Invocation;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

/**

  • ClassName:DownloadService <br/>
  • Function: 文件下載. <br/>
  • Reason: ADD REASON. <br/>
  • Date: 2016年9月28日 下午4:44:37 <br/>
  • @author wpengfei
  • @version
  • @since JDK 1.6
  • @see

*/
@Service
public class DownloadService {

  
private Logger logger = Logger.getLogger(this.getClass());  

/** 
 * downLoad:(文件下載). <br/> 
 * 
 * @author wpengfei 
 * @param inv 
 * @param fileName 
 * @param path 
 * @throws IOException 
 * @since JDK 1.6 
 */  
public void downLoad(Invocation inv, String fileName, String path) throws IOException {  
      
    File file = new File(path);// 構(gòu)造要下載的文件  
    if (file.exists()) {  

        InputStream ins = null;  
        BufferedInputStream bins = null;  
        OutputStream outs = null;  
        BufferedOutputStream bouts = null;  

        try {  

            ins = new FileInputStream(path);// 構(gòu)造一個(gè)讀取文件的IO流對(duì)象  
            bins = new BufferedInputStream(ins);// 放到緩沖流里面  
            outs = inv.getResponse().getOutputStream();// 獲取文件輸出IO流  
            bouts = new BufferedOutputStream(outs);  
              
            String path1 = inv.getRequest().getSession().  
             getServletContext().getRealPath("/WEB-INF/downloads");  
              
            logger.info(path1);  

            inv.getResponse().setContentType("application/x-download");// 設(shè)置response內(nèi)容的類型  
            inv.getResponse().setHeader("Content-disposition",  
                    "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));// 設(shè)置頭部信息  

// inv.getResponse().setContentLength((int)file.length());

            int bytesRead = 0;  
            byte[] buffer = new byte[8192];  

            // 開(kāi)始向網(wǎng)絡(luò)傳輸文件流  
            while ((bytesRead = bins.read(buffer, 0, 8192)) != -1) {  

                bouts.write(buffer, 0, bytesRead);  
            }  
            bouts.flush();// 這里一定要調(diào)用flush()方法  

        } catch (Exception e) {  

            e.printStackTrace();  
        } finally {  
            if (bouts != null) {  

                bouts.close();  
            }  
            if (outs != null) {  
                  
                outs.close();  
            }  
            if (bins != null) {  

                bins.close();  
            }  
            if (ins != null) {  

                ins.close();  
            }  
        }  
    } else {  
        logger.info("導(dǎo)出的文件不存在");  
    }  
}  
  
  
  
  

}

package com.wt.common.util;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Map;

import freemarker.template.Configuration;
import freemarker.template.Template;

/**

  • @Desc:word操作工具類
  • @Author:
  • @Date:2014-1-22下午05:03:19

*/
public class WordUtil {

  
  
@SuppressWarnings("rawtypes")  
public static String createWord2(Map dataMap, String templateName, String filePath, String fileName) {  
    try {  
        // 創(chuàng)建配置實(shí)例  
        Configuration configuration = new Configuration();  

        // 設(shè)置編碼  
        configuration.setDefaultEncoding("UTF-8");  

        // ftl模板文件統(tǒng)一放至 com.lun.template 包下面  
        configuration.setClassForTemplateLoading(WordUtil.class, "\\com\\wt\\common\\util\\");  

        // 獲取模板  
        Template template = configuration.getTemplate(templateName);  

        // 輸出文件  
        File outFile = new File(filePath + File.separator + fileName);  

        // 如果輸出目標(biāo)文件夾不存在,則創(chuàng)建  
        if (!outFile.getParentFile().exists()) {  
            outFile.getParentFile().mkdirs();  
        }  

        // 將模板和數(shù)據(jù)模型合并生成文件  
        Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "UTF-8"));  

        // 生成文件  
        template.process(dataMap, out);  

        // 關(guān)閉流  
        out.flush();  
        out.close();  
          
        return filePath + File.separator + fileName;  
    } catch (Exception e) {  
        e.printStackTrace();  
    }  
      
    return null;  
}  

}

package com.wt.controllers.test1;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import net.paoding.rose.web.Invocation;
import net.paoding.rose.web.annotation.Path;
import net.paoding.rose.web.annotation.rest.Get;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.wt.common.util.CommonsUtil;
import com.wt.common.util.Constants;
import com.wt.common.util.ResponseObject;
import com.wt.common.util.WordUtil;
import com.wt.service.download.DownloadService;

/**

  • @Desc:生成word
  • @Author:
  • @Date:2014-1-22下午04:52:03

*/
@Path("/word")
public class WordController {

  
@Autowired  
private DownloadService downloadService;  

private String filePath; //文件路徑  

// private String fileName; //文件名稱

private String fileOnlyName; //文件唯一名稱  
  
  
  
/** 
 * createWord2:(這里用一句話描述這個(gè)方法的作用). <br/> 
 * localhost:8080/test1/word/createWord2 
 * 
 * @author wpengfei 
 * @param inv 
 * @return 
 * @throws IOException  
 * @since JDK 1.6 
 */  
@Get("/createWord2")  
public String createWord2(Invocation inv) throws IOException {  
      
    /** 用于組裝word頁(yè)面需要的數(shù)據(jù) */  
    Map<String, Object> dataMap = new HashMap<String, Object>();  
      
    SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日");  
      
    dataMap.put("startTime", sdf.format(new Date()));  
    dataMap.put("endTime", sdf.format(new Date()));  
    dataMap.put("count", 1);  
    dataMap.put("username", "Tom");  
    dataMap.put("courseName", "物理");  
    dataMap.put("className", "1班");  
    dataMap.put("materialName", "體育學(xué)");  
    dataMap.put("materialVer", 1.0);  
    dataMap.put("teachAim", "諾克爾12421價(jià)是否可驕傲了空間阿凡達(dá)撿垃圾覅文件附件安防奇偶萬(wàn)佛諾克爾12421價(jià)是否可驕傲了空間阿凡達(dá)撿垃圾覅文件附件安防奇偶萬(wàn)佛諾克爾12421價(jià)是否可驕傲了空間阿凡達(dá)撿垃圾覅文件附件安防奇偶萬(wàn)佛諾克爾12421價(jià)是否可驕傲了空間阿凡達(dá)撿垃圾覅文件附件安防奇偶萬(wàn)佛諾克爾12421價(jià)是否可驕傲了空間阿凡達(dá)撿垃圾覅文件附件安防奇偶萬(wàn)佛");  
      
    //文件導(dǎo)出的目標(biāo)路徑  
    filePath=Constants.UPLOAD_BASE_FOLD;  
      
    StringBuffer sb=new StringBuffer();  
    sb.append(sdf.format(new Date()));  
    sb.append("_");  
    Random r=new Random();  
    sb.append(r.nextInt(100));  
    //文件唯一名稱  
    fileOnlyName = "testDoc11_"+sb+".doc";  
      
    /** 生成word */  
    String result = WordUtil.createWord2(dataMap, "testDoc11.ftl", filePath, fileOnlyName);  
      
    if(StringUtils.isNotBlank(result)){  
          
        downloadService.downLoad(inv, fileOnlyName, result);  
    }  
      
    return "@";  
}  
 

}

2017年11月26日 10:28
編輯回答
不舍棄

我也遇到了這個(gè)問(wèn)題,有什么好的解決辦法嗎?

2018年8月21日 17:54
編輯回答
卟乖

樓主問(wèn)題解決了嗎 我也遇到這個(gè)問(wèn)題 求教

2017年6月14日 14:58
編輯回答
兔囡囡

這是freemarker生成word文檔的通病,它本質(zhì)上還是一個(gè)xml文本,可以看看:http://www.xdocin.com/office....,它的結(jié)果是真正的docx格式

2018年1月18日 12:58