学习内容:SSH框架 记录excel导出功能开发
记录excel导出功能开发
1、开发环境:ssh 全栈开发
2、 excel文档模板内容填充
3、 另存为xml (有可能无法保存选择(XML 电子表格2003 (*.xml) 格式)) 再把后缀改成ftl
4、 复制内容至项目位置
学习实例:
前端部分
//layui 点击下载保存文档按钮
<a class="layui-btn layui-btn-xs" href="javascript:void(0)"lay-event="createNewWord">导出Excel</a>
//调用方法
else if(obj.event === 'createNewWord'){
// window.location.href = "/risen/project/risen_review_meeting/createNewWord.action?uuid=" + data.uuid;
$.ajax({
type: "get",
url: "/risen/project/risen_review_meeting/createNewWord.action?uuid=" + data.uuid,
success: function (data) {
if(data.success){
window.location.href = "/risen/project/risen_review_meeting/exportWord.action?fileAbsolute=" + data.records;
}else {
layer.msg("服务器异常,请联系管理员处理!");
}
},
error : function() {
layer.msg("网络异常,请稍后再试!");
}
});
return false;
}
SSH 框架:xml调用Action层
<!-- 生成Word -->
<action name="createNewWord" class="risenReviewMeetingAction" method="createNewWord" />
<!-- 导出Word -->
<action name="exportWord" class="risenReviewMeetingAction" method="exportWord">
<result name="success" type="stream">
<param name="contentType">application/octet-stream</param>
<param name="inputName">fileStream</param>
<param name="contentDisposition">attachment;filename="${fileName}"</param>
</result>
</action>
Action层
/**
/**
* 生成Word文档
* @return
*/
public String createNewWord(){
//获取生成的Word文档的绝对路径
String fileAbsolute = getRisenReviewMeetingService().exportWord(getModel());
getModel().setResult(fileAbsolute);
return SUCCESS;
}
/**
* 导出Word
* @return
*/
public String exportWord(){
try {
fileName = URLEncoder.encode("专家经费审评及支付明细表.xls", "UTF-8");
File outFile = new File(getModel().getFileAbsolute());
fileStream = new FileInputStream(outFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}finally {
//删除文件
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(60000);
if(StringUtils.hasText(fileName)){
new File(fileName).deleteOnExit();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
return SUCCESS;
}
Sevice层 及Impl 实现类方法
//-----------------------接口-----------------------------
/**
* 生成文档
* @param model
* @return
*/
String exportWord(RisenReviewMeeting model);
//------------------------impl实现方法----------------------------
@Override
public String exportWord(RisenReviewMeeting model) {
Map<String,Object> dataMap = new HashMap<>();
List<RisenExpert> expertList ;
if(!StringUtils.hasText(model.getUuid())){
return null;
}
model = getMyBatisDaoManager().exeSelectOneCommand(model,"getRisenReviewMeeting");
HashMap<Integer, Integer> map = new HashMap<>();
//获得专家的信息
if(StringUtils.hasText(model.getRisenrmExperts())) {
RisenExpert expert = new RisenExpert();
expert.setRisenexRemark(model.getRisenrmExperts());
expertList = risenExpertService.getListByUuidStringList(expert);
dataMap.put("expert",expertList);
}
try {
//expertBudgetReview.ftl 已转化xml,改ftl 文件名
return new WordUtil().setTemplate("expertBudgetReview.ftl").setDataModel(dataMap).export("专家经费审评及支付明细表");
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
文档模板->xml->改后缀ftl格式,需要遍历的数据模块
<#list data.expert as item>
<Row>
<Cell ss:StyleID="s66"><Data ss:Type="Number">${(item.index)!""}</Data></Cell>
<Cell ss:StyleID="s67"><Data ss:Type="String">${(item.risenexName)!""}</Data></Cell>
<Cell ss:StyleID="s67"><Data ss:Type="String">${(item.risenexWorkunit)!""}</Data></Cell>
<Cell ss:StyleID="s68"><Data ss:Type="String">${(item.risenexJob)!""}</Data></Cell>
<Cell ss:StyleID="s69"><Data ss:Type="String">${(item.risenexIdnumber)!""}</Data></Cell>
<Cell ss:StyleID="s68"><Data ss:Type="String">${(item.risenexBank)!""}</Data></Cell>
<Cell ss:StyleID="s69"><Data ss:Type="String">${(item.risenexBankId)!""}</Data></Cell>
<Cell StyleID="s70"/>
<Cell ss:StyleID="s68"/>
</Row>
</#list>
WordUtil 工具类
package com.risen.project.utils.export;
import com.opensymphony.xwork2.ActionContext;
import com.risen.core.service.aop.UniteExecutorAOPService;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.apache.commons.collections.map.DefaultedMap;
import org.apache.struts2.ServletActionContext;
import org.springframework.util.StringUtils;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* Word导出
* @author Sulongx
*/
public class WordUtil {
//资源数据
private Map<String,Object> dataMap;
//模板全局配置
private static Configuration config = new Configuration();
//模板文件路径
private static String templatePath;
//"水桶"
private static byte[] buff = new byte[1024*8];
//动态模板
private Template template;
//响应体
private HttpServletResponse response;
//响应流
private OutputStream webOut;
//文件输出字符流
private BufferedWriter outFile;
//文件输入字节流
private FileInputStream redFile;
//加载模板和模板文件
static {
//设置默认编码
config.setDefaultEncoding("UTF-8");
//读取模板文件路径
templatePath = WordUtil.class.getResource("/").getPath() + "/com/risen/project/template/";
}
//设置响应体
private void initWeb(String fileName) throws IOException {
}
/**
* 设置导出Word模板
* @param src 文件名
* 请将模板放置在template目录下
* @return
*/
public WordUtil setTemplate(String src) throws IOException {
if(!StringUtils.hasText(src)){
throw new RuntimeException("参数 src:模板不能未空");
}
config.setDirectoryForTemplateLoading(new File(templatePath));
template = config.getTemplate(src);
return this;
}
/**
* 设置导入数据资源Model
* @param dataModel
* @return
*/
public WordUtil setDataModel(Object dataModel){
if(dataModel == null){
throw new RuntimeException("参数 dataModel:数据源不能未空");
}
dataMap = new HashMap<String, Object>();
dataMap.put("data",dataModel);
return this;
}
/**
* 导出
* @param fileName 文件名
*/
public String export(String fileName) {
if(templatePath == null){
throw new RuntimeException("模板未加载,请先加载模板");
}
if(dataMap == null){
throw new RuntimeException("资源数据未加载,请先加载资源数据");
}
try {
String fileAbsolute = templatePath + fileName + UUID.randomUUID().toString().replaceAll("-","") + ".doc";
File file = new File(fileAbsolute);
outFile = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file),"UTF-8"));
template.process(dataMap,outFile);
outFile.flush();
return fileAbsolute;
//返写入response响应流
// redFile = new FileInputStream(templatePath + fileName + ".doc");
// ActionContext actionContext = ActionContext.getContext();
// response = (HttpServletResponse) actionContext.get(ServletActionContext.HTTP_RESPONSE);
// response.reset();
// webOut = response.getOutputStream();
// int hasRead = 0;
// while ((hasRead = redFile.read(buff)) != -1){
// webOut.write(buff,0,hasRead);
// }
//
// //设置响应体文件格式
// response.setCharacterEncoding("UTF-8");
// response.setContentType("application/msword");
// response.setHeader("contentType","application/octet-stream");
// response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName,"UTF-8") + ".doc");
// response.flushBuffer();
}catch (Exception e){
e.printStackTrace();
}finally {
closeResource();
}
return null;
}
/**
* 指定文件目录导出
* @param fileName
* @param outPath
*/
public void export(String fileName,String outPath){
}
//关闭资源
private void closeResource(){
if(outFile != null){
try {
outFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(redFile != null){
try {
redFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}