`

java导出2007版word(docx格式)freemarker + xml 实现

 
阅读更多

Freemarker+xml生成docx

原理概述:word从2003版就支持xml格式,而freemarker是java封装的模板工具,两者结合也就是在xml中需要动态生成的部分调用freemarker的指令(类似于EL表达式),来生成我们需要的数据,再用流输出文件,就达到了写word的效果。

 

生成word的基本流程图如下:

 

1.       生成docx模板和xml模板

 

生成docx模板

 

按照项目需要生成固定格式的docx格式的模板。

为方便测试做了个简单的例子,docx模板的内容如下图:

 

生成xml模板

 

从docx模板中取出word/document.xml,由于docx属于zip格式,可以用winrar打开,如图:

 

 

 

除word文件夹外其它文件为基本配置文件,取出word/document.xml(存放word文件的文本内容)如下图:

 

 

 

需要把document.xml解压出来,修改里面需要从数据库导出的数据用freemarker的指令代替,例如${test} 同时可以用遍历函数

替换完成后相当于生成了xml模板

2.       利用freemarker填充数据并生成word文件

 

 

这里把数据库中的数据放到map中,把map和xml模板交给freemarker来生成(填充完数据)的xml具体实现方法如下:

package com.hannet.yigehui;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;


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

public class XmlToExcel {
	
	
	private static XmlToExcel tplm = null;
	 private Configuration cfg = null;

	 private XmlToExcel() {
	  cfg = new Configuration();
	 try {
	  //注册tmlplate的load路径
	   cfg.setClassForTemplateLoading(this.getClass(), "/template/");
	  } catch (Exception e) {
	   
	  }
	 }

	 private static Template getTemplate(String name) throws IOException {
	  if(tplm == null) {
	   tplm = new XmlToExcel();
	  }
	  return tplm.cfg.getTemplate(name);
	 }
	 
	 /**
	  * 
	  * @param templatefile 模板文件
	  * @param param        需要填充的内容
	  * @param out			填充完成输出的文件
	  * @throws IOException
	  * @throws TemplateException
	  */
	 public static void process(String templatefile, Map param ,Writer out) throws IOException, TemplateException{
	  //获取模板
	  Template template=XmlToExcel.getTemplate(templatefile);
	  template.setOutputEncoding("UTF-8");
	  //合并数据
	  template.process(param, out);
	  if(out!=null){
			out.close();
		}
	 }
}

 

利用java的zipFile 和 ZipOutputStream 及zipFile.getInputStream() 来根据docx模板导出 (需要把word/document.xml文件替换成(填充完数据)的xml)具体操作流程如下:

 

package com.hannet.yigehui;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

import freemarker.template.TemplateException;

/**
 * 其实docx属于zip的一种,这里只需要操作word/document.xml中的数据,其他的数据不用动
 * @author yigehui
 *
 */
public class XmlToDocx {
	
	/**
	 * 
	 * @param documentFile  动态生成数据的docunment.xml文件
	 * @param docxTemplate	docx的模板
	 * @param toFileName	需要导出的文件路径
	 * @throws ZipException
	 * @throws IOException
	 */
	
	public  void outDocx(File documentFile,String docxTemplate,String toFilePath) throws ZipException, IOException {
	
		try {
		String fileName = XmlToDocx.class.getClassLoader().getResource("").toURI().getPath()+docxTemplate;
			
			File docxFile = new File(fileName);
			ZipFile zipFile = new ZipFile(docxFile);			
			Enumeration<? extends ZipEntry> zipEntrys = zipFile.entries();
			ZipOutputStream zipout = new ZipOutputStream(new FileOutputStream(toFilePath));
			int len=-1;
			byte[] buffer=new byte[1024];
			while(zipEntrys.hasMoreElements()) {
				ZipEntry next = zipEntrys.nextElement();
				InputStream is = zipFile.getInputStream(next);
				//把输入流的文件传到输出流中 如果是word/document.xml由我们输入
				zipout.putNextEntry(new ZipEntry(next.toString()));
				if("word/document.xml".equals(next.toString())){
					//InputStream in = new FileInputStream(new File(XmlToDocx.class.getClassLoader().getResource("").toURI().getPath()+"template/test.xml"));
					InputStream in = new FileInputStream(documentFile);
					while((len = in.read(buffer))!=-1){
						zipout.write(buffer,0,len);
					}
					in.close();
				}else {
					while((len = is.read(buffer))!=-1){
						zipout.write(buffer,0,len);
					}
					is.close();
				}		
			}			
			zipout.close();			
		} catch (URISyntaxException e) {
			e.printStackTrace();
		}catch (FileNotFoundException e) {
			e.printStackTrace();
		}	
	}
}

  

这里输出的文件即为完整的docx格式的word文件

 

测试调用的代码:

public static void main(String[] args) throws IOException, TemplateException {

		//xml的模板路径*/*
		String xmlTemplate = "test.xml";
		
		//设置docx的模板路径 和文件名
		String docxTemplate = "template/test.docx";
		String toFilePath = "d:\\test.docx";
		
		//填充完数据的临时xml
		String xmlTemp = "d:\\temp.xml";
		Writer w = new FileWriter(new File(xmlTemp));
		
		//1.需要动态传入的数据
		Map<String,Object> p = new HashMap<String,Object>();
		List<String> students = new ArrayList<String>();
		students.add("张三");
		students.add("李四");
		students.add("王二");		
		p.put("test", "测试一下是否成功");
		p.put("students", students);
		
		//2.把map中的数据动态由freemarker传给xml
		XmlToExcel.process(xmlTemplate, p, w);
		
		//3.把填充完成的xml写入到docx中
		XmlToDocx xtd = new XmlToDocx();
		xtd.outDocx(new File(xmlTemp), docxTemplate, toFilePath);
		}

 

分享到:
评论

相关推荐

    freemarker导出doc及docx

    导出docx文件通常涉及到将Freemarker模板转换成OpenXML格式,这是.docx文件的内部结构。可以使用开源库如Apache POI或者docx4j来实现。Apache POI提供了一系列API,可以用来创建、修改和读取Microsoft Office文件,...

    java freemarker导出word -包含多张图片导出

    在Java应用中,使用FreeMarker导出Word文档可以提供灵活的文本和数据结合的方式,尤其适用于生成报告、合同等复杂格式的文档。本篇将详细介绍如何使用FreeMarker与Java结合来导出包含多张图片的Word文档。 1. **...

    Java导出Word文档的实现.docx

    本文将探讨如何使用Java高效地实现Word文档导出,主要聚焦于利用XDocReport和FreeMarker模板引擎的方式。 首先,Java中导出Word文档有多种途径,包括: 1. **Hutool的Word工具类**:这是一个简洁易用的Java工具库...

    Java 用Freemarker导出word文档总结

    在Java中利用FreeMarker导出Word文档,可以极大地提高代码的可维护性和灵活性。 首先,我们需要了解FreeMarker的基础知识。FreeMarker是一个基于模板的视图技术,它将数据模型和视图模板分离,使得开发者可以专注于...

    java使用freemarker模板技术导出word

    Java 使用 FreeMarker 模板技术导出 Word 是一种常见的数据动态生成文档的方法,它结合了 Java 的编程能力和 FreeMarker 模板引擎的强大功能,能够帮助开发者高效地生成结构化的 Word 文档。FreeMarker 是一个开源的...

    freemaker导出多个word格式doc压缩文件.rar

    通过上述步骤,你可以实现FreeMarker导出多份Word文档并将其打包成RAR文件的功能。在实际开发中,可能还需要考虑错误处理、并发生成、模板缓存等问题,以提高效率和健壮性。FreeMarker的强大之处在于其灵活性和可...

    java利用FreeMarker导出word

    - 在这个场景中,POI用于读取Word文档(`.docx`格式其实是ZIP压缩包,包含XML文件),将其内容解析为Java对象,然后这些对象可以作为数据模型供FreeMarker使用。 5. **模板设计**: - FreeMarker模板设计时,需要...

    java freemarker 导出 word

    以上就是使用Java FreeMarker导出Word文档的基本流程。实际应用中,你可能需要处理更复杂的模板,包括表格、列表、图片等,以及更丰富的数据模型。FreeMarker的强大之处在于它的灵活性,可以根据具体需求定制模板,...

    Java用freemarker导出word例子

    本篇文章将详细介绍如何使用Java结合FreeMarker来实现Word文档的导出。 1. **FreeMarker简介** FreeMarker是一个基于模板的开源Java库,用于生成文本输出,如HTML、XML或其他任何基于文本的格式。它的主要应用场景...

    java 使用 freemarker 导出word 包含 图片和动态的数据表,动态行和动态列

    在Java开发中,导出Word文档是一项常见的任务,特别是在企业级应用中,如报表生成、数据导出等。本篇文章将深入探讨如何使用FreeMarker模板引擎来生成包含图片和动态数据表的Word文档,尤其注重动态行和动态列的处理...

    freemarker 导出word表格

    总结,FreeMarker导出Word表格的核心在于理解XML结构,创建FreeMarker模板,以及正确地绑定数据。这个方法的好处是可以将格式设计与数据分离,使得数据的更新和格式的维护变得更加灵活和高效。在处理大量数据的导出...

    Java html转word 使用FreeMarker

    当我们需要在Web应用中生成可编辑的文档或者将网页内容导出为Word格式时,`FreeMarker`是一个非常实用的工具。这个标题“Java html转word 使用FreeMarker”暗示了一个Java项目,它利用FreeMarker模板引擎来实现HTML...

    java导出word文档,固定模板

    注意,由于Freemarker生成的是XML格式,所以最终的输出文件通常需要通过Apache POI等库转化为标准的Word文档(`.docx`格式)。 这个过程完成后,你就可以利用Java和Freemarker技术,根据需求动态生成Word文档了。这...

    javaword文档导出jar包freemarker.rar

    JavaWord文档导出jar包与Freemarker是一个用于在Java后端生成动态Word文档的解决方案。这个rar压缩包中包含的jar文件可以帮助开发者利用Freemarker模板语言将数据动态地填充到Word文档中,实现自动化文档生成。下面...

    java使用word模板导出个人简历

    本教程将探讨如何利用Java和特定的模板引擎,如Freemarker,来处理Word模板,生成doc和docx格式的个人简历文件。以下是相关知识点的详细说明: 1. **Freemarker模板引擎**: Freemarker是一个强大的、开源的模板...

    导出Word:POI or Freemarker

    对于Word的导出,POI提供了低级别的API操作,可以直接操作Word文档的XML结构,实现高度定制化的文档生成。 1. 使用POI导出Word: 在简单的文档生成场景中,如仅需填充固定模板的数据,你可以直接使用POI操作.docx...

    java导出word之freemarker导出程序

    下面我们将深入探讨如何使用Java结合Freemarker实现Word文档的导出,并提供一个入门实例的解析。 首先,让我们了解Freemarker的基本概念。Freemarker是一个开源的Java模板引擎,它可以将简单的文本模板与数据模型相...

    java通过freemarker模板导出word含图片

    在Java开发中,有时我们需要将数据以Word文档的形式导出,尤其在报表生成、文档自动化等领域。本示例关注的是如何使用FreeMarker模板引擎来实现这个功能,并且包含在Word文档中插入图片的能力。FreeMarker是一个强大...

    java+freemarker实现对word的操作myeclipse工程Java源码

    Apache POI是一个广泛使用的库,它允许Java程序读写Microsoft Office格式的文件,包括Word(.doc和.docx)。使用Apache POI,你可以创建新的Word文档,插入文本、图片、表格等元素,或者读取已有文档的内容。 在本...

Global site tag (gtag.js) - Google Analytics