您的位置:首页 > 其它

通过freemaker生成复杂Word文档(带有图片)

2017-11-29 15:59 477 查看
我的是maven项目,所以需要添加依赖:

<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>


生成一个testdoc.doc模版(根据需求而定),内容如下:



然后另存为Word XML文档



之后通过notepad打开,将 {sx},{sqr}中间不相关的删除



然后将图片所在位置的一串代码替换成${image}(随便写,视需求而定)



保存之后,将testdoc.xml改个后缀名ftl,即文件名为testdoc.ftl,并放到项目中。

以下是生成word所需要的工具类:

public class WordUtils {

private static Configuration configuration = null;
//这里注意的是利用WordUtils的类加载器动态获得模板文件的位置
private static final String templateFolder = WordUtils.class.getClassLoader().getResource("../../").getPath() + "resources/";

static {
configuration = new Configuration();
configuration.setDefaultEncoding("utf-8");
try {
System.out.println(templateFolder);
configuration.setDirectoryForTemplateLoading(new File(templateFolder));
} catch (IOException e) {
e.printStackTrace();
}
}

private WordUtils() {
throw new AssertionError();
}

public static void exportMillCertificateWord(HttpServletRequest request, HttpServletResponse response, Map map) throws IOException {
Template freemarkerTemplate = configuration.getTemplate("test.ftl");
File file = null;
InputStream fin = null;
ServletOutputStream out = null;
try {
// 调用工具类的createDoc方法生成Word文档
file = createDoc(map,freemarkerTemplate);
fin = new FileInputStream(file);

response.setCharacterEncoding("utf-8");
response.setContentType("application/msword");
// 设置浏览器以下载的方式处理该文件名
String fileName = "申请单.doc";
response.setHeader("Content-Disposition", "attachment;filename="
.concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8"))));

out = response.getOutputStream();
byte[] buffer = new byte[512];  // 缓冲区
int bytesToRead = -1;
// 通过循环将读入的Word文件的内容输出到浏览器中
while((bytesToRead = fin.read(buffer)) != -1) {
out.write(buffer, 0, bytesToRead);
}
} finally {
if(fin != null) fin.close();
if(out != null) out.close();
if(file != null) file.delete(); // 删除临时文件
}
}

private static File createDoc(Map<?, ?> dataMap, Template template) {
String name =  "test.doc";
File f = new File(name);
Template t = template;
try {
// 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开
Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");
t.process(dataMap, w);
w.close();
} catch (Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
return f;
}

//将图片转换成BASE64字符串
public static String getImageString(InputStream in) throws IOException {
//InputStream in = null;
byte[] data = null;
try {
// in = new FileInputStream(filename);
data = new byte[in.available()];
in.read(data);
in.close();
} catch (IOException e) {
throw e;
} finally {
if (in != null)
in.close();
}
BASE64Encoder encoder = new BASE64Encoder();
return data != null ? encoder.encode(data) : "";
}

}


以下是Controller:

@Controller
public class WordController extends BaseFormController{

@RequestMapping(value="bpm/bmfw/printWord",method=RequestMethod.GET)
public void printWord(HttpServletRequest request,HttpServletResponse response){

Map<String, Object> map = new HashMap<String, Object>();

String path = request.getSession().getServletContext().getRealPath("resources")+File.separator+fileName;//这是将要放到word文档中图片的地址

try {

InputStream in = getMulFileByPath(path).getInputStream();
String reportImage = WordUtils.getImageString(in);

map.put("sx", "test申请单");
map.put("sqr", "张三");
map.put("image", reportImage);//xml文档中的占位符名称对应

WordUtils.exportMillCertificateWord(request,response,map);

/*File file = new File(path);
if(file.exists() && file.isFile()){
file.delete();
System.out.println("删除"+fileName+"成功");
}*/

} catch (Exception e) {

e.printStackTrace();
}

}

private static MultipartFile getMulFileByPath(String picPath) {
FileItem fileItem = createFileItem(picPath);
MultipartFile mfile = new CommonsMultipartFile(fileItem);
return mfile;
}

private static FileItem createFileItem(String filePath){
FileItemFactory factory = new DiskFileItemFactory(16, null);
String textFieldName = "textField";
int num = filePath.lastIndexOf(".");
String extFile = filePath.substring(num);
FileItem item = factory.createItem(textFieldName, "text/plain", true,
"MyFileName" + extFile);
File newfile = new File(filePath);
int bytesRead = 0;
byte[] buffer = new byte[8192];
try{
FileInputStream fis = new FileInputStream(newfile);
OutputStream os = item.getOutputStream();
while ((bytesRead = fis.read(buffer, 0, 8192)) != -1){
os.write(buffer, 0, bytesRead);
}
os.close();
fis.close();
}
catch (IOException e){
e.printStackTrace();
}
return item;
}

}


大功告成!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: