JavaWeb将前台table导出Excel

最近的工作和excel较上劲了,本来这是一个及其简单的问题,只要用到POI就可以解决,但是由于需要的导出表格页面太多,在后台进行书写十分麻烦,一起工作的小伙伴们想从前台通过JS导出,这样就轻松很多,但是经过我们的尝试后发现从前台导出会遇到各种浏览器问题,导出中文乱码问题等等。。。
最后我选择利用表单提交的方式解决这一问题,代码稍后放上,在整个过程中遇到的问题有:
1,由于ajax无法弹出下载窗体所以被无情PASS掉了,这种最简单粗暴的解决方式注定与我无缘
2,url传值时由字符限制,用这个方式解决时开始并没有发现问题,当根据年份选择显示的数据过多时,url过长应该是被浏览器拦截了,百度了一下说各个浏览器的限制不一样,不建议通过修改浏览器设置来解决
3,java只能接收前台传过来的字符串,数组不可以传递(原谅我竟然忘了这一点)
下面贴上代码,首先是JS文件,主要写了三个函数,分别是将table中的数据写成json格式方便传值;将表头作为key值写成数组,传递到后台用字符串接受并用逗号分隔成数组即可,这部分的原因是在后台用迭代器遍历json对象的属性时是无序的;最后一个是在JS中创建表单,并将前两部分的json,数组以及文件名写到表单中的文本框中。

function getJson(tableid){

    var tableObj = document.getElementById(tableid);
    var jsonStr = '[';
    for (var i = 0; i < tableObj.rows.length; i++) {    //遍历Table的所有Row
        jsonStr += '{';
        for (var j = 0; j < tableObj.rows[i].cells.length; j++) {   //遍历Row中的每一列
            jsonStr += '"'+tableObj.rows[0].cells[j].innerText+'":"'+tableObj.rows[i].cells[j].innerText+'",';
        }
        jsonStr = jsonStr.substring(0,jsonStr.length-1);
        jsonStr += '},'
    }
    jsonStr = jsonStr.substring(0,jsonStr.length-1);
    jsonStr += ']'
    return jsonStr;
}
function getHeads(tableid){
    var tableObj = document.getElementById(tableid);
    var arr = new Array();
    for (var i = 0; i < tableObj.rows[0].cells.length; i++) {
         arr[i] = tableObj.rows[0].cells[i].innerText;
    }
    return arr;
}
function toAction(tableid,name){
    var jsonStr = getJson(tableid);
    var filename = name;
    var arr = getHeads(tableid);
    var formElement = document.createElement('form');
    document.body.appendChild(formElement); 
    formElement.setAttribute('id','form');
    formElement.setAttribute('name','form');
    formElement.setAttribute('action','/anBM/tongji/toExcel/download.action');
    formElement.setAttribute('method','post');

    var inputTextElement = document.createElement('input');
    inputTextElement.setAttribute('id','json');
    inputTextElement.setAttribute('name','json');
    inputTextElement.setAttribute('type','text');
    inputTextElement.setAttribute('value',jsonStr);
    formElement.appendChild(inputTextElement);
    var inputTextElement1 = document.createElement('input');
    inputTextElement1.setAttribute('id','filename');
    inputTextElement1.setAttribute('name','filename');
    inputTextElement1.setAttribute('type','text');
    inputTextElement1.setAttribute('value',filename);
    formElement.appendChild(inputTextElement1);
    var inputTextElement2 = document.createElement('input');
    inputTextElement2.setAttribute('id','str');
    inputTextElement2.setAttribute('name','str');
    inputTextElement2.setAttribute('type','text');
    inputTextElement2.setAttribute('value',arr);
    formElement.appendChild(inputTextElement2);
    document.getElementById("form").submit();
}

下面是后台控制层代码

@Controller
@Scope(value = "prototype")
@Namespace(value = "/tongji/toExcel")
@Results({
        @Result(name = ActionSupport.SUCCESS, type = "json")})
public class tableToExcelAction extends BaseAction{
    private String strs;
    private String filename;
    private String str;
    @Action(value = "download")
    public String toExcel() throws Exception{
        HttpServletResponse response = getResponse();
        HttpServletRequest request = getRequest();
        response.setContentType("application/vnd.ms-excel");  
        response.setCharacterEncoding("utf-8");
        HSSFWorkbook wb = new HSSFWorkbook();
        HSSFSheet sheet = wb.createSheet("sheet1");

        strs = new String(request.getParameter("json"));
        String[] heads = new String(request.getParameter("str")).split(",");
        JSONArray jsonArray = new JSONArray(strs);
        int iSize = jsonArray.length();
        for (int i = 0; i < iSize; i++) {
            HSSFRow row = sheet.createRow(i);
            JSONObject jsonObj = jsonArray.getJSONObject(i);
            for(int j = 0;jnew HSSFRichTextString(jsonObj.getString(heads[j]));    
                cell.setCellValue(text);
            }
        }
        filename = new String(request.getParameter("filename"));
        response.setHeader("Content-disposition","attachment;filename="+new String(filename.getBytes("gbk"), "iso8859-1")+".xls");
        OutputStream outputStream = response.getOutputStream();  
        wb.write(outputStream); 
        outputStream.flush();  
        outputStream.close();
        return null;
    }



    public String getStrs() {
        return strs;
    }



    public void setStrs(String strs) {
        this.strs = strs;
    }



    public String getFilename() {
        return filename;
    }

    public void setFilename(String filename) {
        this.filename = filename;
    }



    public String getStr() {
        return str;

在JSP页面调用JS

$("#d_button").click(function(){
    var filename = "filename";  
    toAction("table",filename);
});

好了,就这些了。因为是从后台完成的写入excel并下载的操作,所以应该适用于各个浏览器,同时这种方法只适合table不分页的情况。做这些的原因也是为了让项目中其他人方便使用。明天项目要有新的进展了,准备将数据用echarts显示在各种图上。

你可能感兴趣的:(JavaWeb)