国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

上傳Excel文件使用JXL解析

2019-11-15 01:05:49
字體:
來源:轉載
供稿:網友
上傳Excel文件使用JXL解析

  繼續昨天的說,昨天說到用fullcalendar日期控件來顯示日程,現在有一個需求是讀取Excel中的日程信息,然后顯示在日歷上,繼續記錄備忘。

一、上傳文件

  上傳文件也困惑了我很久,今天一起記錄一下。項目框架是SSH的,所以上傳文件就使用了struts2的fileupload,所需要的jar包都在引入struts2的時候引入了,然后就是直接上代碼操作了。

1.1 頁面
<form id="excelform" action="。。。。。。。。。" method="post" enctype="mult

上傳文件的form必不可少的就是enctype="multipart/form-data",文件域中的accept=".xlsx,.xls"表示接收上傳的文件類型,當然也可以在struts2的攔截器里面設置上傳文件的大小、上傳文件的類型等信息,我這里使用的是另一種方式:

<!-- 指定允許上傳的文件最大字節數。默認值是2097152(2M) -->    <constant name="struts.multipart.maxSize" value="1048576"/>    <!-- 設置上傳文件的臨時文件夾,默認使用javax.servlet.context.tempdir -->    <constant name="struts.multipart.saveDir " value="d:/tmp" />

文件接收類型在文件域中設置,允許上傳文件的大小在struts2的配置文件中直接使用constant設置了,上面我標紅的代碼要注意一下,上次我在本地設置的D盤,但是放到服務器上的時候,服務器只有C盤沒有D盤,然后就一直報錯,害的我折騰了好久才看出來,這個是用來存儲上傳文件的臨時文件夾。

1.2 JS提交表單

使用AjaxForm的方式提交表單,因此要引入jquery和jquery form的js文件

//提交表單    $("#excelform").ajaxForm({        beforeSubmit: showRequest, //表單驗證        success: showResponse //成功返回    });function showRequest(){        var filename = $("#source").val();        if(filename == null || filename == ''){            alert("請選擇文件...");            $("#source").focus();            return false;        }        $("#excelform").attr("action", "。。。。。。");    }    function showResponse(responseText, statusText){        if(statusText=="success") {                if(responseText == "1") {                alert("Excel文件導入成功");                //重新獲取所有事件數據                $('#calendar').fullCalendar('refetchEvents');            } else {                alert(responseText);            }        } else {            alert(statusText);        }    }
1.3 后臺實現
private File excel;    private String excelContentType;    private String excelFileName;

fileupload上傳文件時,先接收上面的三個參數,File 的名稱要跟文件域的name屬性一致,文件名稱和文件類型前面要加上文件域的name屬性。

public String importEvent() throws IOException {        // 獲取文件存儲路徑          // get the path to save the file        String path = ServletActionContext.getRequest().getRealPath("/WEB-INF/upload");                path += FileUtil.getPath();// child path        // 獲取文件存儲名稱        // get the name save to        String name = FileUtil.getName(excelFileName);        // upload the file and return the target file object        File file = FileUtil.upload(excel, path, name);

  在獲取文件存儲路徑這里,我更喜歡使用String path = request.getsession().getServletContext().getRealPath("/WEB-INF/upload");因為ServletActionContext.getRequest().getRealPath("/WEB-INF/upload");現在已經不推薦使用了。

  為了讀取時方便,因此當天上傳的文件放在upload文件夾下面的以當天日期命名的文件夾中,為了避免重復,以當前日期時間對當前文件進行重命名。

public static String getPath(){        Date date = new Date();        sdf.applyPattern("/yyyy-MM-dd");        return sdf.format(date);    }public static String getName(String fileName){        Date date = new Date();        sdf.applyPattern("HH-mm-ss");        return sdf.format(date) + getSuffix(fileName);    }    /**     * @param fileName     * @return     */    public static String getSuffix(String fileName){        int dotIndex = fileName.lastIndexOf('.');        return fileName.substring(dotIndex);    }

  因為主要目的是解析上傳的Excel文件,因此,上傳文件之后返回該文件進行解析,具體上傳步驟:

/**     * @param source     * @param dest     * @return      */    public static File upload(File src, String path, String name) {        File directory = new File(path);        if(!directory.exists()){            directory.mkdirs();        }        File dest = new File(path, name);        if(upload(src, dest)){            return dest;        }        return null;    }/**     * @param src     * @param dest     */    public static boolean upload(File src, File dest) {        BufferedInputStream bis = null;        BufferedOutputStream bos = null;        byte[] buf = new byte[1024];        int len = 0;        try {            bis = new BufferedInputStream(new FileInputStream(src));            bos = new BufferedOutputStream(new FileOutputStream(dest));            while (((len = bis.read(buf)) != -1)) {                bos.write(buf, 0, len);            }        } catch (Exception e) {            e.printStackTrace();            return false;        } finally {            try {                if (bos != null) {                    bos.close();                }                if (bis != null) {                    bis.close();                }            } catch (Exception e) {                bos = null;                bis = null;            }        }        return true;    }

上面就是文件上傳的過程,上傳成功后對該文件進行解析,解析Excel使用的JXL的方式,也可以使用POI的方式解析。

二、JXL解析EXCEL
public boolean importEvent(File file) {                ExcelUtil excel = new ExcelUtil();        ExcelContent eContent = excel.getFromExcel(file);        if(eContent == null){            return false;        }        List<Agenda> alist = agendaDAO.getFromExcelContent(eContent);        return agendaDAO.batchSave(alist);    }

EXCEL表格可以理解為一個二維數組,因此使用List套List的方式來存儲讀取出來的內容;

public class ExcelContent {    private List<String> title;//標題    private List<List<String>> content;//內容

從excel文件中讀取信息存儲到ExcelContent 中:

/**     * get contents from a excel file     * @param file----the excel file path     * @param hasTitle     * @return     */    public ExcelContent getFromExcel(File file) {        Workbook rwb = null;        ExcelContent eContent = new ExcelContent();        List<List<String>> datas = new ArrayList<List<String>>();        try {            rwb = Workbook.getWorkbook(file);            Sheet sheet = rwb.getSheet(0);// deploy the first sheet            int rows = sheet.getRows();            // start to loop and get the datas            for (int index = 0; index < rows; index++) {                Cell[] cells = sheet.getRow(index);                List<String> row = new ArrayList<String>();                for (Cell cell : cells) {                    row.add(getContent(cell));                }                if(index == 0){// title banner                    eContent.setTitle(row);                } else {                    datas.add(row);                }            }            eContent.setContent(datas);        } catch (Exception e) {            return null;        }        return eContent;    }

首先需要構建一個workbook對象,也就是工作薄,可以是一個文件,也可以是一個輸入流,

InputStreamis=newFileInputStream(sourcefile);

Workbookrwb=Workbook.getWorkbook(is);

  獲取到工作薄之后就是獲取到工作表了,也就是sheet,這里只有一個工作表,所以使用了Sheet sheet = rwb.getSheet(0);如果一個工作薄里面有多個工作表,那么可以使用

Sheet[] sheets = rwb.getSheets();然后循環對每個sheet進行操作即可,int sheets = rwb.getNumberOfSheets();可以獲取到sheet的數量。

  獲取到sheet之后就可以對一個工作表進行操作了,int rows = sheet.getRows();表示獲取到該sheet中的行數,int rsColumns = rs.getColumns();表示獲取到總列數;

知道總行數之后循環取出每一行的數據 Cell[] cells = sheet.getRow(index);表示取出第index行的數據,取數據的時候,由于EXCEL表格中存在日期格式的,因此要對數據進行簡單的處理:

/**     * excel format     * @param cell     * @return     */    private String getContent(Cell cell){        CellType type = cell.getType();        if(type == CellType.DATE){            DateCell c = (DateCell) cell;            return sdf.format(c.getDate());        }        return cell.getContents();    }

取出的第一行數據為標題,后面的為正式的數據,如果沒有標題,那就不需要處理標題了。取出excel中的數據后,將其放在實現準備好的eContent 對象中返回,之后再從eContent 取出數據,存入數據庫

/**      * attention: no id include!!!     * convert the Excel content to agenda objects without id included     * @param eContent----the Excel content     * @return a list of agenda objects     */    public List<Agenda> getFromExcelContent(ExcelContent eContent){                List<String> title = eContent.getTitle();// excel title        List<List<String>> contents = eContent.getContent();// excel rows                List<Agenda> aList = new ArrayList<Agenda>();                int len = title.size();        // loop the all excel content        for(List<String> row : contents){            Agenda agenda = new Agenda();            for(int i = 0; i < len; i++){                String cell = row.get(i);                String field = title.get(i);                if(field.equalsIgnoreCase("title")){// title field                    agenda.setTitle(cell.trim());                } else if(field.equalsIgnoreCase("allday")){// all day field                    if(cell.matches("[yY1]")){                        agenda.setAllDay(true);                    } else if(cell.matches("[nN0]")){                        agenda.setAllDay(false);                    }                } else if(field.equalsIgnoreCase("starttime")){// start time field                    if(!StringUtil.isSpace(cell)){                        agenda.setStart(DateUtil.parse2Date(cell, format));                    }                } else if(field.equalsIgnoreCase("endtime")){// end time field                    if(!StringUtil.isSpace(cell)){                        agenda.setEnd(DateUtil.parse2Date(cell, format));                    }                } else if(field.equalsIgnoreCase("color")){// color field                    agenda.setColor(cell.trim());                } else if(field.equalsIgnoreCase("user")){// user field                    agenda.setUser(cell.trim());                } else if(field.equalsIgnoreCase("supporter")){// supporter field                    agenda.setSupporter(cell.trim());                }            }            aList.add(agenda);        }        return aList;    }

這里面唯一要說的就是starttime和endtime,在excel文件中,這兩個數值為時間戳,因此到這里之后需要對時間戳進行處理,轉換成時間之后才能存入數據庫;

 public static Date timeStamp2Date(String seconds,String format) {              if(seconds == null || seconds.isEmpty() || seconds.equals("null")){                  return null;              }              if(format == null || format.isEmpty()) format = "yyyy-MM-dd HH:mm:ss";              SimpleDateFormat sdf = new SimpleDateFormat(format);                          String str = sdf.format(new Date(Long.valueOf(seconds+"000")));            return parse2Date(str,format);          } 

返回的alist在持久化層進行批量存儲即可,這樣讀取EXCEL就完成了。

三、導出EXCEL

  頁面在上傳文件的時候已經給出了,導出啟程就是查詢數據庫的日程,然后導出為一個excel文件即可。

3.1 JS實現
//export agenda    $("#export").click(function(){        $("#excelform").attr("action", "。。。。。。");        document.forms[0].submit();    });

將上面上傳的form的action改成導出的action,提交表單即可。

3.2 后臺實現
/**     * @return     * @throws IOException     */    public String exportEvent() throws IOException {        // start to output        response.addHeader("Content-Disposition", "attachment;filename=events.xls");        response.setContentType("application/octet-stream");        ServletOutputStream ss = response.getOutputStream();        OutputStream stream = new BufferedOutputStream(ss);        boolean success = excelServ.exportEvent(stream);        if(!success){            response.reset();            response.setContentType("text/plain");            PrintWriter out = response.getWriter();            out.print("failed");            out.flush();            out.close();        }        return null;    }

  response.addHeader("Content-Disposition", "attachment;filename=events.xls"); response.setContentType("application/octet-stream");這兩句是用戶點擊下載按鈕時,可以彈出提示框用戶可以選擇直接打開還是下載,牽扯到http協議的一些東西,我也不是太懂,只知道是這么寫,但是太具體的我就不知道了,大家感興趣的可以自己了解一下。

  下載設置好之后就是讀取數據庫數據,轉換成excel格式了。

/**     *  export events to Excel file     * @return     */    public boolean exportEvent(OutputStream os) {        List<Agenda> alist = agendaDAO.findAll();        if(alist == null || alist.size() == 0){            return false;        }        List<List<String>> content = new ArrayList<List<String>>();        for(Agenda agenda : alist){            // add the agenda property to a String row            List<String> row = new ArrayList<String>();            row = agenda.toListString();            content.add(row);        }        ExcelUtil excel = new ExcelUtil();        excel.exportToExcel(os, Agenda.getPrintHead(), content);        return true;    }

  前面說過excel數據就是一個二維數組,因此,可以先將查詢出的日程列表進行處理,轉換成List<List<String>>形式,為了實現這種功能,我在agenda中添加了toListString()方法:

/**     * used to convert the Agenda object to String list     * @return list of string array stands for every filed     */    public List<String> toListString(){        // add the agenda property to a String row        List<String> row = new ArrayList<String>();        row.add(String.valueOf(id));        row.add(title);                String format = "yyyy-MM-dd";        if(!allDay){            format = "yyyy-MM-dd HH:mm";        }        row.add(DateUtil.parse2String(start, format));        row.add(DateUtil.parse2String(end, format));        row.add(StringUtil.bool2String(allDay));        row.add(color);        row.add(this.user + " ");        row.add(this.supporter + " ");        return row;    }

返回一個String類型的list集合,添加到content中,之后再獲取到要導出的數據的標題,也在agenda中實現:

/**     * @return the String array used to export the agenda object to excel     */    public static String[] getPrintHead(){        return new String[]{"ID", "title", "starttime", "endtime", "allday", "color", "user", "supporter"};    }

這兩個處理完成之后,再加上輸出流即可開始導出excel文件:

/**     * export to excel     * @param os----the output stream of excel file to save     * @param title----the array of the title banner     * @param content----a array list of the data to save     * @return     */    public void exportToExcel(OutputStream os, String[] title, List<List<String>> content) {        WritableWorkbook workbook = null;//create the excel        WritableSheet sheet = null;//create excel sheet        // start        try {            workbook = Workbook.createWorkbook(os);            sheet = workbook.createSheet("sheet1", 0);            int rowNum = 0;            // whether the title include in the source file            if (title != null && title.length != 0) {                /********** format the excel cell *************/                WritableCellFormat title_style = cellFormat.getCellFormat(ExcelCellFormat.TITLE_CENTER);                for (int i = 0; i < title.length; i++) {                    sheet.addCell(new Label(i, 0, title[i], title_style));                }                rowNum++;            }            WritableCellFormat text_style = cellFormat.getCellFormat(ExcelCellFormat.TEXT_LEFT);            for (List<String> rows : content) {                int colNum = 0;                for (String obj : rows) {                    if (obj == null) {                        obj = "";                    }                    Label la = new Label(colNum, rowNum, obj,text_style);                    sheet.addCell(la);                    colNum++;                }                rowNum++;            }            workbook.write();// write the content to the file stream        } catch (Exception e) {            e.printStackTrace();        } finally {// close            try {                if (workbook != null) {                    workbook.close();                }            } catch (Exception e) {                e.printStackTrace();            }        }    }

  與讀取excel文件類似,首先要使用workbook類的工廠方法創建一個可寫入的工作薄,這里要注意的是,只能通過 API提供的工廠方法來創建Workbook,而不能使用WritableWorkbook的構造函數,因為類WritableWorkbook的構造函 數為protected類型。

  創建可寫入的工作薄有兩種方法,一種是file:

  jxl.write.WritableWorkbookwwb=Workbook.createWorkbook(newFile(targetfile));

  一種是輸出流:

  1. OutputStreamos=newFileOutputStream(targetfile);
  2. jxl.write.WritableWorkbookwwb=Workbook.createWorkbook(os);

本文使用輸出流的方式進行導出,工作薄創建完成之后就需要創建工作表,使用sheet = workbook.createSheet("sheet1", 0);創建工作表,兩個參數分別表示工作表的名稱和工作表在工作薄中的位置。

工作薄和工作表設置好之后就是對內容進行設置了,jxl提供對單元格及其單元格中的內容進行設置的方式,比如設置字體、設置字體顏色等等。

public class ExcelCellFormat {        public static int TITLE_CENTER = 0;    public static int TEXT_LEFT = 1;    public static int CELLFORMATE_TEXT_RIGHT = 2;        public WritableCellFormat getCellFormat(int type) throws WriteException {        WritableCellFormat cellFormat = null;        if (TITLE_CENTER == type) {// 用于標題居中            WritableFont BoldFont = new WritableFont(WritableFont.ARIAL,10, WritableFont.BOLD);            cellFormat = new WritableCellFormat(BoldFont);            cellFormat.setBorder(Border.ALL, BorderLineStyle.THIN);            cellFormat.setVerticalAlignment(VerticalAlignment.CENTRE); // 用于文字垂直            cellFormat.setAlignment(Alignment.CENTRE); // 文字水平對齊            cellFormat.setWrap(false); // 文字是否換行        } else if (TEXT_LEFT == type) {// 用于正文居左            WritableFont NormalFont = new WritableFont(WritableFont.ARIAL, 10);            cellFormat = new WritableCellFormat(NormalFont);            cellFormat.setBorder(Border.NONE, BorderLineStyle.THIN); // 線條            cellFormat.setVerticalAlignment(VerticalAlignment.CENTRE); // 文字垂直對齊            cellFormat.setAlignment(Alignment.LEFT); // 文字水平對齊            cellFormat.setWrap(false); // 文字是否換行        } else if (CELLFORMATE_TEXT_RIGHT == type) {// 用于正文居左            WritableFont NormalFont = new WritableFont(WritableFont.ARIAL, 10);            cellFormat = new WritableCellFormat(NormalFont);            cellFormat.setBorder(Border.NONE, BorderLineStyle.THIN); // 線條            cellFormat.setVerticalAlignment(VerticalAlignment.CENTRE); // 文字垂直對齊            cellFormat.setAlignment(Alignment.RIGHT); // 文字水平對齊            cellFormat.setWrap(false); // 文字是否換行        }        return cellFormat;    }}

上面的內容表示對單元格中內容的一些設置,其他的設置大家可以查查API就可以了。

  上面就是使用JXL進行excel的導入導出的全部內容了,有說的不對的地方歡迎大家指正。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 池州市| 彰武县| 溆浦县| 化州市| 石屏县| 本溪市| 富平县| 棋牌| 鹿邑县| 惠州市| 资兴市| 彭山县| 丹棱县| 平度市| 图们市| 姚安县| 利川市| 山阴县| 德江县| 新巴尔虎左旗| 马山县| 海盐县| 略阳县| 明光市| 台江县| 佛冈县| 两当县| 河北省| 平顶山市| 乐都县| 揭阳市| 兴安盟| 左云县| 双峰县| 广东省| 玛多县| 泾川县| 阿尔山市| 桐城市| 平潭县| 江华|