`
uule
  • 浏览: 6305440 次
  • 性别: Icon_minigender_1
  • 来自: 一片神奇的土地
社区版块
存档分类
最新评论

JAVA生成WORD工具类

 
阅读更多

该方法借助freemarker的JAR包即可。

参考:

使用freemarker生成word

Java Web项目中使用Freemarker生成Word文档(带图片)

Java使用freemark生成word

 

WordXML格式初步分析

doc模板说明文档 

 

所需工具:

JS/HTML格式化工具

 

步骤:

1、在word中编辑好模版样式,设置好占位符,注意图片最好先黏上去



 

 

2、在word中,文件-另存为-XML格式

 

3、使用工具格式化上图的XML文件

a.在表格数据的TR中加入<#list myListData as tmp> 和</#list>

b.将XML文件中图片的BASE64转换为相应的占位符

 

4、在Eclipse中新建文件teample-pic.ftl,将XML的数据粘贴进去

 

5、使用工具类WordUtil.java生成word文件

 

代码:

package com.test;

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

import sun.misc.BASE64Encoder;
import freemarker.template.Configuration;
import freemarker.template.Template;

public class WordUtil {

	/**
	 * @param dataMap
	 *            word中需要展示的动态数据,用map集合来保存
	 * @param templateName
	 *            word模板名称,例如:teample.ftl
	 * @param filePath
	 *            文件生成的目标路径,例如:D:/
	 * @param fileName
	 *            生成的文件名称
	 */
	@SuppressWarnings("unchecked")
	public static void createWord(Map dataMap, String templateName,
			String filePath, String fileName) {
		try {
			// 创建配置实例
			Configuration configuration = new Configuration();

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

			// ftl模板文件
			configuration.setClassForTemplateLoading(WordUtil.class,
					"/com/test/");

			// 获取模板
			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();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
	
	
	/**
	 * 将图片转换为BASE64为字符串
	 * @param filename
	 * @return
	 * @throws IOException
	 */
	public static String getImageString(String filename) 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) : "";  
   } 

}

 

package com.test;

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;

public class TestJava2Word {

	public static void main(String[] args) throws IOException {
		createWord();
		//String BASE64 = WordUtil.getImageString("D://doc//friend.jpg");
		//System.out.println(BASE64);
	}
	
	public static void createWord() {
        Map<String, Object> dataMap = new HashMap<String, Object>();
        
        /** 组装数据 */
        dataMap.put("username","张三");
        dataMap.put("address","深圳市南山区西丽镇");
        dataMap.put("num", Math.floor(Math.random()*10));
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日");
        dataMap.put("date",sdf.format(new Date()));        
        dataMap.put("content","华语天王周杰伦在北京召开周杰伦战略发布会。在发布会上,推出时尚与专业结合的:引起了广泛的关注和讨论。现在终于正式与大家见面,天猫、官网同时上线,首卖期间还有好礼相赠!买就送,就是这么任性!");
        
        List<Map<String, Object>> newsList=new ArrayList<Map<String,Object>>();
        for(int i=1;i<=10;i++){
         Map<String, Object> map=new HashMap<String, Object>();
         map.put("name", "王"+i);
         map.put("tel", "137"+i);
         map.put("age", "年龄"+i);
         map.put("address", System.currentTimeMillis());
         newsList.add(map);
        }
        dataMap.put("myListData",newsList);
        
        String myPic = "";
        String myPic2 = "";
        try {
			 myPic = WordUtil.getImageString("D://doc//ganen.jpg");
			 myPic2 = WordUtil.getImageString("D://doc//friend.jpg");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
       
        dataMap.put("myPic", myPic);
        dataMap.put("myPic2", myPic2);
                
        //文件路径
        String filePath= "D://doc";
        
        //文件名称
        String fileName = System.currentTimeMillis()+".doc";
        
        /** 生成word */
        WordUtil.createWord(dataMap, "teample-pic.ftl", filePath, fileName);
    }
	
	
}


 

模版文件:

teample.ftl等见附件。

 

 

注意两个问题:

1、如果图片是网络图片时,getImageString() 方法中不可使用本地new FileInputStream处理图片,应该使用new URL()获取链接,然后openConnection(),最后connection.getInputStream()获取流

 

2、InputStream流转Byte[]时,使用new byte[in.available]可能会有问题,推荐使用IOUtils.toByteArray(in) 转换为byte数组


java中InputStream转化为byte[]数组

 在commons-io包中org.apache.commons.io.IOUtils类的toByteArray(InputStream input)已经有实现了,我们可以参考下思路,完成我们的方法,我们可以用类似下面的代码实现inputStream转化为byte[]数组

public static byte[] toByteArray(InputStream input) throws IOException {
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    byte[] buffer = new byte[4096];
    int n = 0;
    while (-1 != (n = input.read(buffer))) {
        output.write(buffer, 0, n);
    }
    return output.toByteArray();
}

 

下面是IOUtils中摘录出与toByteArray相关的方法

org.apache.commons.io.IOUtils.toByteArray

方法如下:
public static byte[] toByteArray(InputStream input)
  throws IOException
{
  ByteArrayOutputStream output = new ByteArrayOutputStream();
  copy(input, output);
  return output.toByteArray();
}

public static int copy(InputStream input, OutputStream output)
  throws IOException
{
  long count = copyLarge(input, output);
  if (count > 2147483647L) {
    return -1;
  }
  return (int)count;
}

public static long copyLarge(InputStream input, OutputStream output)
  throws IOException
{
  byte[] buffer = new byte[4096];
  long count = 0L;
  int n = 0;
  while (-1 != (n = input.read(buffer))) {
    output.write(buffer, 0, n);
    count += n;
  }
  return count;
}

 。。。

 

 

 

  • 大小: 100.2 KB
分享到:
评论
1 楼 18335864773 2019-04-16  
推荐用 pageoffice 组件生成 word 文件。

相关推荐

Global site tag (gtag.js) - Google Analytics