java如何将xml类型的word文档转换为word类型的文档

发布于 2022-09-07 08:24:29 字数 1385 浏览 30 评论 0

我的需求是这样的:
word文档类型是xml,用文本编辑器打开看到以下代码(我只拷贝了头部部分代码)
java如何能把它转换为word类型的doc文档,Apache的poi好像只能把word文档转换成xml、html等格式的,但不能反过来转。请问有没有解决过这种需求的朋友,先谢谢了!

<?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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

心欲静而疯不止 2022-09-14 08:24:29

大致的思路是先用office2003或者2007编辑好word的样式,然后另存为xml,将xml翻译为FreeMarker模板,最后用java来解析FreeMarker模板并输出Doc。经测试这样方式生成的word文档完全符合office标准,样式、内容控制非常便利,打印也不会变形,生成的文档和office中编辑文档完全一样。
用xml做导出方案。

先创建一个word文档,按照需求在word中填好一个模板,然后把对应的数据换成变量${},然后将文档保存为xml文档格式,使用文档编辑器打开这个xml格式的文档,去掉多余的xml符号,使用Freemarker读取这个文档然后替换掉变量,输出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);// 构造要下载的文件  
    if (file.exists()) {  

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

        try {  

            ins = new FileInputStream(path);// 构造一个读取文件的IO流对象  
            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");// 设置response内容的类型  
            inv.getResponse().setHeader("Content-disposition",  
                    "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));// 设置头部信息  

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

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

            // 开始向网络传输文件流  
            while ((bytesRead = bins.read(buffer, 0, 8192)) != -1) {  

                bouts.write(buffer, 0, bytesRead);  
            }  
            bouts.flush();// 这里一定要调用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("导出的文件不存在");  
    }  
}  
  
  
  
  

}

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 {  
        // 创建配置实例  
        Configuration configuration = new Configuration();  

        // 设置编码  
        configuration.setDefaultEncoding("UTF-8");  

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

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

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

        // 如果输出目标文件夹不存在,则创建  
        if (!outFile.getParentFile().exists()) {  
            outFile.getParentFile().mkdirs();  
        }  

        // 将模板和数据模型合并生成文件  
        Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "UTF-8"));  

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

        // 关闭流  
        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:(这里用一句话描述这个方法的作用). <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页面需要的数据 */  
    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", "体育学");  
    dataMap.put("materialVer", 1.0);  
    dataMap.put("teachAim", "诺克尔12421价是否可骄傲了空间阿凡达捡垃圾覅文件附件安防奇偶万佛诺克尔12421价是否可骄傲了空间阿凡达捡垃圾覅文件附件安防奇偶万佛诺克尔12421价是否可骄傲了空间阿凡达捡垃圾覅文件附件安防奇偶万佛诺克尔12421价是否可骄傲了空间阿凡达捡垃圾覅文件附件安防奇偶万佛诺克尔12421价是否可骄傲了空间阿凡达捡垃圾覅文件附件安防奇偶万佛");  
      
    //文件导出的目标路径  
    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 "@";  
}  
 

}

甜警司 2022-09-14 08:24:29

@smilesnake 首先感谢分享代码,可能是我的问题,没有把问题描述清楚,我目前就是按照你的思路来做的,但问题是最后给用户生成的这个doc文档是xml类型的(另存为的时候能够看到)并且用户打开编辑后再去另存的时候就变成了xml为后缀的文档了,导致后面打不开,所以我的问题是如何能生成word类型的文档

你的呼吸 2022-09-14 08:24:29

这是freemarker生成word文档的通病,它本质上还是一个xml文本,可以看看:http://www.xdocin.com/office....,它的结果是真正的docx格式

浪荡不羁 2022-09-14 08:24:29

楼主问题解决了吗 我也遇到这个问题 求教

删除→记忆 2022-09-14 08:24:29

楼主问题解决了吗 我也遇到这个问题 求教

美胚控场 2022-09-14 08:24:29

我也遇到了这个问题,有什么好的解决办法吗?

帝王念 2022-09-14 08:24:29

楼主的问题解决了吗?我也遇到了这个问题,求大神教教!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文