Boot+freemarker导出word文档

968 阅读1分钟

背景:业务业务,纯粹业务需要,导出pdf或者word尝试了很多方法,决定还是freemarker比较舒适,接下来讲一下操作步骤。

1、maven引入

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>


2、确定word模板并占位符标识


蓝色标识框 可以直接用freemarker指令标识上,例如 ${data.name}。如果不用freemarker,也可以如图对象属性名称标识,利于后期xml修改。

黄色标识框 最好列一行数据,list语法循环生成的word<w:tcW w:w="1681" w:type="dxa"/>,第一列是1681,第二列就变了,很好奇没找到答案,然后写算法。


3、模板转存成 .xml 格式


4、修改后缀为.ftl


5、freemarker指令

参考中文官方手册:   freemarker.foofun.cn/ref_directi…

每行5个算法

<#list risks as risk>

	<#-- 判断第一个生成 w:tr 标签  -->
	<#if risk_index%5  == 0>
		<w:tr>	
	<#-- 判断不是第四个但是已经后面没有数据 /w:tr 结尾标签  -->
	<#if risk_index == (risks?size-1) && risk_index%5!=4>
		</w:tr>
	</#if>
	<#-- 判断第四个生成 /w:tr 结尾标签  -->
	<#if risk_index%5  == 4>
		</w:tr>	
	</#if>
</#list>

判断选中

<w:tc>
	<#-- 判断选择方框对勾 begin  -->
	<#if risk.selected==1>
		<#-- 选择 -->
		<w:r>
			<w:rPr>
				<w:rFonts w:hint="eastAsia" w:ascii="仿宋_GB2312"/>
				<w:b/>
				<w:sz w:val="18"/>
				<w:szCs w:val="18"/>
			</w:rPr>
			<w:sym w:font="Wingdings 2" w:char="0052"/>
		</w:r>
		<w:r>
			<w:rPr>
				<w:rFonts w:hint="eastAsia" w:ascii="仿宋_GB2312"/>
				<w:b/>
				<w:sz w:val="18"/>
				<w:szCs w:val="18"/>
			</w:rPr>
			<w:t xml:space="preserve"> </w:t>
		</w:r>
		<#-- 未选□ -->
		<#else>
			<w:r>
				<w:rPr>
					<w:rFonts w:hint="eastAsia" w:ascii="仿宋_GB2312"/>
					<w:b/>
					<w:sz w:val="18"/>
					<w:szCs w:val="18"/>
				</w:rPr>
				<w:t xml:space="preserve"></w:t>
			</w:r>
		</#if>
		<#-- 判断选择方框对勾 end  -->
		<w:r>
			<w:rPr>
				<w:rFonts w:hint="eastAsia" w:ascii="仿宋_GB2312"/>
				<w:sz w:val="18"/>
				<w:szCs w:val="18"/>
			</w:rPr>
			<#-- 循环取出名称 -->
			<w:t>${risk.riskName}</w:t>
		</w:r>
	</w:p>
</w:tc>


6、WordUtil导出方法exportWord

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.io.Writer;

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

public class IwmWordUtil {

	@SuppressWarnings("deprecation")
	private static Configuration configuration = new Configuration();
	/**
	 * 
	 * @param entity 占位符需要的freemarker数据
	 * @param template_src 模板文件路径  (注意:文件路径,例如:/a.ftl)
	 * @param downFileName 输出文件名称
	 * @param out_src 输出文件夹路径(注意:文件夹路径,例如:/file/,如果是需要响应到页面下载,则需要自己写一个response流响应到页面)
	 */
	public static void exportWord(Object entity, String template_src, String downFileName, String out_src) {
		configuration.setDefaultEncoding("UTF-8");
		configuration.setClassicCompatible(true);
		try {
			String str = readFile(new File(template_src));
			Template t = new Template("name", new StringReader(str), configuration);
			File outFile = new File(out_src);
			if (!outFile.exists()) {
				outFile.mkdirs();
			}
			File tmpFile = File.createTempFile(downFileName, ".doc", outFile);
			Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(tmpFile), "UTF-8"));
			t.process(entity, out);
			out.flush();
			out.close();
			System.err.println("生成word成功,文件名: " + tmpFile.getName());
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * 读取文件
	 * 
	 * @param file
	 * @return
	 * @throws IOException
	 */
	public static String readFile(File file) throws IOException {
		// 文件很长的话建议使用StringBuffer
		StringBuffer FileContent = new StringBuffer();
		FileInputStream fis = null;
		InputStreamReader isr = null;
		BufferedReader br = null;
		try {
			fis = new FileInputStream(file);
			isr = new InputStreamReader(fis, "UTF-8");
			br = new BufferedReader(isr);
			String line = null;
			while ((line = br.readLine()) != null) {
				FileContent.append(line);
				FileContent.append("\r\n"); // 补上换行符
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new IOException(e.getMessage());
		} finally {
			try {
				if (fis != null) {
					fis.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if (isr != null) {
					isr.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if (br != null) {
					br.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return FileContent.toString();
	}
}