1.工具类WordUtils.java
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.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.utility.DateUtil;
public class WordUtils {
//配置信息,代码本身写的还是很可读的,就不过多注解了
private static Configuration configuration = null;
//这里注意的是利用WordUtils的类加载器动态获得模板文件的位置
// private static final String templateFolder = WordUtils.class.getClassLoader().getResource("../../").getPath() + "WEB-INF/templetes/";
static {
configuration = new Configuration();
configuration.setDefaultEncoding("utf-8");
configuration.setClassForTemplateLoading(WordUtils.class,"/com/iyoungsun/safe/utils"); //这里要把ftl文件放在WordUtils类同目录里
}
private WordUtils() {
throw new AssertionError();
}
public static void exportMillCertificateWord(HttpServletRequest request, HttpServletResponse response, Map map,String title,String ftlFile) throws IOException {
Template freemarkerTemplate = configuration.getTemplate(ftlFile);
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");
// 设置浏览器以下载的方式处理该文件名
Date currentTime = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString = formatter.format(currentTime);
String fileName = title+dateString+ ".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;
}
}
2.关于处理图片方法
//获得图片的base64码
@SuppressWarnings("deprecation")
public String getImageBase(String src) {
if(src==null||src==""){
return "";
}
File file = new File(getRequest().getRealPath("/")+src.replace(getRequest().getContextPath(), ""));
if(!file.exists()) {
return "";
}
InputStream in = null;
byte[] data = null;
try {
in = new FileInputStream(file);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
try {
data = new byte[in.available()];
in.read(data);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(data);
}
3.下面是我项目的接口方法,我使用的是jFinal
public void exportWord(){
Calendar calendar = Calendar.getInstance();// 取当前日期。
int id = getParaToInt("id");
if(id>0){
String sql = "SELECT ypr.id,yd.id as d_id,yd.name AS dname,yps.comment,yps.level,ypr.integral,ypr.record_time,ypr.supervise_name,ypr.ban,ypr.location,ypr.work_ticket,ypr.job_manager,ypr.work_content,ypr.problem "
+ "FROM ys_probity_standard yps JOIN ys_project_record ypr ON ypr.standard_id = yps.id "
+ "JOIN ys_department yd ON yd.id = ypr.department_id "
+ "WHERE yps.level != '' AND yps.level NOT IN ('廉政禁令','质量禁令') AND ypr.id="+id;
List<ProjectRecord> list = ProjectRecord.dao.find(sql);
Map<String, Object> map = new HashMap<String, Object>();
for (int i = 0; i < list.size(); i++) {
String location = list.get(i).get("location");
String time = list.get(i).get("record_time");
String supervise_name = list.get(i).get("supervise_name");
String dname = list.get(i).get("dname");
String work_ticket = list.get(i).get("work_ticket");
String job_manager = list.get(i).get("job_manager");
String work_content = list.get(i).get("work_content");
String problem = list.get(i).get("problem");
String level = list.get(i).get("level");
String comment = list.get(i).get("comment");
String integral = list.get(i).get("integral");
//获得数据
map.put("date_num", calendar.get(Calendar.YEAR)+"");
map.put("location", location!=null?location:"");
map.put("record_time",time!=null?time:"");
map.put("supervise_name",supervise_name!=null?supervise_name:"");
map.put("dname", dname!=null?dname:"");
map.put("work_ticket", work_ticket!=null?work_ticket:"");
map.put("job_manager", job_manager!=null?job_manager:"");
map.put("work_content", work_content!=null?work_content:"");
map.put("problem", problem!=null?problem:"");
map.put("level", level!=null?level:"");
map.put("comment", comment!=null?comment:"");
map.put("integral", !"0".equals(integral)?integral:"违反安全禁令");
}
//查询图片
List<YsImage> yiListall = YsImage.dao.find("select * from ys_image where ys_image.pid=" + id);
List<String> imgList = new ArrayList<String>();;
for (int i = 0; i <yiListall.size(); i++) {
String image = yiListall.get(i).get("image");
imgList.add(getImageBase(image)!=null?getImageBase(image):"");
}
map.put("imgList",imgList);
try {
WordUtils.exportMillCertificateWord(getRequest(),getResponse(),map,"督查记录","abc.ftl");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
4.关于.ftl文件模板的配置方法
(1)首先在word上编辑好自己的模板,下面是建的样式
注意有图片的话最好随便一两个图片
(2)然后最好用office打开,点击按钮另存为word 2003 .xml 文件,然后将另存好的.xml文件copy到开发工具
里面,编辑修改,我这里有三个图片,先将
<w:binData w:name="${"wordml://0300000"+qy_index+1+".png"}" xml:space="preserve"></w:binData>里的base64码删掉,
然后用list循环
注意:<#list></#list>一定要写对位置
最后将文件的后缀改为.ftl,这样模板就做好了