jsf中用java代码把一个list的内容导出到本地excel

头头今天给我一个任务,要我写一个接口,其实就是方法啦,然后让其他人调用,能直接把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~,哈哈,我开玩笑的,百度知道,百科,文库,经验都挺好的~)






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值