头头今天给我一个任务,要我写一个接口,其实就是方法啦,然后让其他人调用,能直接把xhtml页面上显示的table给导出到本地的excel;
先说解决方案:
1.用primefaces的jar包,用法很简单:
<p:dataTable id="children_types" var="children_type"
value="#{treeBean.children_types}">
<p:column headerText="名称">
<h:outputText value="#{children_type.materialName}" />
</p:column>
<p:column headerText="编码">
<h:outputText value="#{children_type.materialCode}" />
</p:column>
</p:dataTable>
假设是这张表格,因为用了primefaces的框架,所以dataTable前面有个p:,至于primefaces怎么用,等我自己用得很溜了,我再专门写篇文章出来,现在不知道从何写起。。。
<h:commandLink>
<p:graphicImage value="/images/excel.jpg" />
<p:dataExporter type="xls" target="children_types" fileName="material" />
</h:commandLink>
<p:graphicImage value="/images/excel.jpg" />这个就是自己设置背景图啦,type指定为xls就是excel的后缀名咯,(改成pdf就能导出pdf,卧槽,primefaces真心强大!)target指定上面表的id,filename就是你指定excel叫啥名。
这样就完成了,so easy,而且我测过了,chrome,ie,firefox三个都兼容;
2.用javascript把xhtml上<table></table>标签中的内容给转成excel,用法嘛,也不难吧:
<script type="text/javascript" language="javascript" src="table.js"> </script>
<h:button οnclick="export_to_excel('hehe')" value="js导出excel" />
引入js的代码我也copy上来了,记得在<dataTable>标签外套一层<div>,像这样:
<div id="hehe">
<dataTable>
...
</dataTable>
</div>
因为这段js代码是根据div的id来找后门的table的内容的,就是页面上显示什么,excel也显示什么,用button的onclick直接调用,把div的id传进去就ok了,但是好像只有chrome可以成功,ie,firefox都不支持,然后就操蛋了~不知道为啥贴上来自动给我加了<span></span>......
function export_to_excel(div_id) {
//getting values of current time for generating the file name
var dt = new Date();
var day = dt.getDate();
var month = dt.getMonth() + 1;
var year = dt.getFullYear();
var hour = dt.getHours();
var mins = dt.getMinutes();
var postfix = year + "." + month + "."+ day + "_" + hour + ":" + mins;
//creating a temporary HTML link element (they support setting file names)
var a = document.createElement('a');
//getting data from our div that contains the HTML table
var data_type = 'data:application/vnd.ms-excel';
var table_div = document.getElementById(div_id);
var table_html = table_div.outerHTML.replace(/ /g, '%20');
a.href = data_type + ', ' + table_html;
//setting the file name
a.download = 'excel' + postfix + '.xls';
//triggering the function
a.click();
};
3.我最后觉得最合适的方法,按照旁边大哥的指点做的,因为jsf中的dataTable用到的数据是托管bean中的一个List,所以只要在后台把这个list的内容导出到excel就ok了~
先附上java类的代码:
package com.zhangbinhui.ManageBean;
import java.io.File;
import java.io.OutputStream;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import jxl.Workbook;
import jxl.format.Alignment;
import jxl.format.Border;
import jxl.format.BorderLineStyle;
import jxl.format.VerticalAlignment;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
/***
* @author lsf
*/
@ManagedBean
@ViewScoped
public class MakeExcel {
/***************************************************************************
* @param fileName
* EXCEL文件名称
* @param listTitle
* EXCEL文件第一行列标题集合
* @param listContent
* EXCEL文件正文数据集合
* @return
*/
String fileName;
String[] Title;
List<Object> listContent;
public String exportExcel(ActionEvent event) {
fileName = (String)event.getComponent().getAttributes().get("filename");
String title = (String)event.getComponent().getAttributes().get("titles");
Title = title.split(",");
listContent = (List<Object>)event.getComponent().getAttributes().get("content");
String result = "系统提示:Excel文件导出成功!";
// 以下开始输出到EXCEL
try {
//定义输出流,以便打开保存对话框______________________begin
HttpServletResponse response=(HttpServletResponse) FacesContext
.getCurrentInstance().getExternalContext().getResponse();
OutputStream os = response.getOutputStream();// 取得输出流
response.reset();// 清空输出流
response.setHeader("Content-disposition",
"attachment; filename="+ new
String(fileName.getBytes("GB2312"),"ISO8859-1")+".xls");
// 设定输出文件头
response.setContentType("application/msexcel");// 定义输出类型
//定义输出流,以便打开保存对话框_______________________end
/** **********创建工作簿************ */
WritableWorkbook workbook = Workbook.createWorkbook(os);
/** **********创建工作表************ */
WritableSheet sheet = workbook.createSheet("Sheet1", 0);
/** **********设置纵横打印(默认为纵打)、打印纸***************** */
jxl.SheetSettings sheetset = sheet.getSettings();
sheetset.setProtected(false);
/** ************设置单元格字体************** */
WritableFont NormalFont = new WritableFont(WritableFont.ARIAL, 10);
WritableFont BoldFont = new WritableFont(WritableFont.ARIAL, 10,
WritableFont.BOLD);
/** ************以下设置三种单元格样式,灵活备用************ */
// 用于标题居中
WritableCellFormat wcf_center = new WritableCellFormat(BoldFont);
wcf_center.setBorder(Border.ALL, BorderLineStyle.THIN); // 线条
wcf_center.setVerticalAlignment(VerticalAlignment.CENTRE); // 文字垂直对齐
wcf_center.setAlignment(Alignment.CENTRE); // 文字水平对齐
wcf_center.setWrap(false); // 文字是否换行
// 用于正文居左
WritableCellFormat wcf_left = new WritableCellFormat(NormalFont);
wcf_left.setBorder(Border.NONE, BorderLineStyle.THIN); // 线条
wcf_left.setVerticalAlignment(VerticalAlignment.CENTRE); // 文字垂直对齐
wcf_left.setAlignment(Alignment.LEFT); // 文字水平对齐
wcf_left.setWrap(false); // 文字是否换行
/** ***************以下是EXCEL开头大标题,暂时省略********************* */
// sheet.mergeCells(0, 0, colWidth, 0);
// sheet.addCell(new Label(0, 0, "XX报表", wcf_center));
/** ***************以下是EXCEL第一行列标题********************* */
for (int i = 0; i < Title.length; i++) {
sheet.addCell(new Label(i, 0, Title[i], wcf_center));
}
/** ***************以下是EXCEL正文数据********************* */
Field[] fields = null;
Field f_value = null;
int i = 1;
for (Object obj : listContent) {
fields = obj.getClass().getDeclaredFields();
int j = 0;
for (Field v : fields) {
f_value = obj.getClass().getDeclaredField(v.getName());
f_value.setAccessible(true);
Object va = f_value.get(obj);
if (va == null) {
va = "";
}
sheet.addCell(new Label(j, i, va.toString(), wcf_left));
j++;
}
i++;
}
/** **********将以上缓存中的内容写到EXCEL文件中******** */
workbook.write();
/** *********关闭文件************* */
workbook.close();
} catch (Exception e) {
result = "系统提示:Excel文件导出失败,原因:" + e.toString();
System.out.println(result);
e.printStackTrace();
}
return result;
}
}
里面用到的包自己去下载好了,http://www.java2s.com/Code/Jar/c/Downloadcomspringsourcecomlowagietext208jar.htm,这个链接,里面几乎有所有你想要的java的jar包。
调用这个java类的方法:
<h:commandButton actionListener="#{makeExcel.exportExcel}" value="java导出excel">
<f:attribute name="filename" value="机器excel" />
<f:attribute name="titles" value="ID,组件,m9变形,警告信息,原因,解决方法,comZh" />
<f:attribute name="content" value="#{machineBean.machineInfo}" />
</h:commandButton>
传三个参数进去,第一个是导出excel的名字,第二个是excel表头栏位,第三个就是把一个上面dataTable用到的list传进去。chrome,ie,火狐都能用,因为他是纯java代码,不像javascript,浏览器内核不同,所以不一定完全支持,而使用java代码导出excel就可以不用考虑浏览器内核不同的因素了。
注意上面定义输出流:
HttpServletResponse response=(HttpServletResponse) FacesContext
.getCurrentInstance().getExternalContext().getResponse();
不同的web框架可能获取输出流的方式不一样,struts用的方法就不一样,不过大同小异,自己上百度google一下就行了。(上百度为了什么?为了上google~,哈哈,我开玩笑的,百度知道,百科,文库,经验都挺好的~)