在ssh框架中使用poi正確導出具有比較高級固定格式的excel 整體過程,查詢導出前後臺下載

来源:http://www.cnblogs.com/youzipi/archive/2016/08/28/zhengjingyouzi.html
-Advertisement-
Play Games

(一) 接需求 : 需求相關 (貼圖 ) 生成三核對文件 1、新增三核對菜單頁面中,增加生成三核對文件功能按鈕,彈窗可根據變電站、電壓等級查詢定值單。 2、定值單信息以表格形式展示,根據選擇情況,生成三核對文件。 整體就是這樣的一個需求,分sheet,合併單元格,設置各種單元格格式,要有序號。 (二 ...


 

(一) 接需求  :   需求相關   (貼圖 )

     生成三核對文件 

1、新增三核對菜單頁面中,增加生成三核對文件功能按鈕,彈窗可根據變電站、電壓等級查詢定值單。

2、定值單信息以表格形式展示,根據選擇情況,生成三核對文件。

整體就是這樣的一個需求,分sheet,合併單元格,設置各種單元格格式,要有序號。

(二)吐槽  

新手,什麼都不會,同事直接給了這麼一個僵硬的需求,哈哈我當時整個人都是懵逼的。一會總結說。

(三)具體流程

全部代碼,控制層,service,前臺,全都貼在最下麵。

1 資料庫查詢

2將信息導出為datatable格式(公司框架)

3將datatable格式轉化為workbook(迴圈遍歷)  使用poi 導出excel  

4workbook生成多SHEET以及合併單元格,單元格賦值,轉換style

5生成workbook後  彈出下載頁面  能夠傳到瀏覽器界面提供下載   (有關springweb框架前後臺傳參數取值問題 )

6中間出現的一些小問題  (全局變數設置  )

 (四)代碼實現與實現過程問題與解決

1 資料庫查詢

 

要生成一個這樣一個excel表格,而我們的信息還沒有獲取到,這時應該考慮如何根據通過前臺傳過來的參數進行一次查詢。(參數為一個,就是能夠獲得一個能關聯到三個表的guid(有一個是無主鍵視圖))

而在查詢過程中也遇到了一些問題。
1. 游標的使用  

把查詢想的太過簡單,關聯三個表的問題研究一會就解決了,但是又出現新的問題,首先資料庫查詢出的信息並不滿足我想要的信息,因為在需求中,那個執行日期執行人和核對日期核對人在我的資料庫查詢語句中是無法實現的,因為他們兩個是一個並行的行,只有一個guid的話,在我的查詢語句中註定只能查出不是執行日期就是核對日期的列。也就是說執行日期核對日期都只是一列中的值,不能並存,只能查出一條。

解決:  網上查了下,使用了一個比較壞的方法:  建立一個游標臨時表,先通過一部分限制條件單獨將執行日期執行人核對日期核對人查出如下

這個就是游標的一種用法,查出這樣的數據後,建立游標,使用forward-only進行順序讀取, 也就是將這兩行兩列的數據從左至右讀取並依次存入name2356中,這樣我們就可以為所欲為了,因為這樣我們可以安排name2356到任何地方,他們中一直都存著我之前給他們賦予的值,因為它們在一個臨時表中,這樣在下麵放入資料庫信息時,我再給它們用as重新命名並且進行拼接,可以直接安放到另一個查詢語句中。  這樣就解決了將不同行的某些信息放入同一行中的問題。

 

2.字元串的拼接。

表格中的信息部分我只能查到單獨的信息,比如執行人和執行日期,這兩個是兩列,如何拼起來讓他們變成一列。

查了一下,這個還是很好解決,使用+和as就可以解決。之前還以為多難。。。。

 

3.一個guid   與   變電站轉化。

  仔細看之前的表格需求,是分sheet的,是以變電站為一個sheet的形式,那麼,我們應當如何做呢。就是分數據源來進行查詢。

傳過來的參數只有guid一個字元串,但是我可以通過guid來查出這些guid中的信息都是哪幾個變電站的。   

1 public List getSubName(String guiddd){
2         StringBuffer sql = new StringBuffer();
3         List list = new ArrayList();
4         sql.append("SELECT DISTINCT CAST(SUBSTATION AS VARCHAR) AS SUBSTATION FROM US_APP.TB_DZD_INFORMATION "+"WHERE  GUID IN  ("+guiddd+")" );
5         list = genericDao.getDataWithSQL(sql.toString());
6         return list;
7     }

 在這樣的資料庫查詢語句中,使用in是如何使用的呢,畢竟in'1,2,3'這樣的格式,和字元串格式還是有點差距。

那麼就是用 1 String guiddd = "'"+guid.replaceAll(",", "','")+"'";//轉換為能夠被數據查詢語句查詢的字元串 這樣,guiddd就能夠使用啦。

我這個邏輯比較亂,如下圖,這樣就完成了分數據源查詢,也就可以分sheet了。

具體資料庫查詢如下。

 1     PlatformConfigUtil.getString("dbtype");
 2                 StringBuffer sql = new StringBuffer();
 3                 sql.append("DECLARE  "
 4                         + "@NAME2 NVARCHAR (300),"
 5                         + "@NAME3 NVARCHAR (300),"
 6                         + "@NAME5 NVARCHAR (300),"
 7                         + "@NAME6 NVARCHAR (300)");
 8                 sql.append("DECLARE CUR CURSOR"
 9                         + " forward_only "
10                         + "FOR SELECT  "
11                         + "TASKACTOR,ENDTIME "
12                         + "FROM US_SYS.TV_WF_TASKLOG "
13                         + "WHERE PROCESSINSTANCE = (");
14                 sql.append("SELECT PROCESSINSTANCE_ "
15                         + "FROM US_SYS.JBPM_VARIABLEINSTANCE "
16                         + "WHERE STRINGVALUE_= ? "//    此處問號
17                         + " AND NAME_ = 'orderNo')");//問號~~~
18                 sql.append("AND (TASKNAME LIKE '執行'"
19                         + " OR TASKNAME LIKE '核對') "
20                         + "AND ENDTIME IS NOT NULL ");
21                 sql.append("OPEN CUR ");
22                 sql.append("FETCH NEXT FROM CUR INTO"
23                         + " @NAME2,@NAME3 ");
24                 sql.append("FETCH NEXT FROM CUR INTO "
25                         + " @NAME5,@NAME6 ");
26                 sql.append("CLOSE CUR ");
27                 sql.append(" DEALLOCATE CUR ");
28                 sql.append(" SELECT ");
29                 sql.append(" ROW_NUMBER() OVER (ORDER BY GUID) AS 'RowNumber',CAST(T1.SUBSTATION AS VARCHAR(500)) AS SUBSTATION, "
30                         + "CAST(T1.EQUIPMENT AS VARCHAR(500)) AS EQUIPMENT, "//設備名稱
31                          + "CAST(T1.EQUIPMENTVERSION AS VARCHAR(500)) AS EQUIPMENTVERSION, "//保護型號
32                          + "CAST(T1.DZDINDEX  AS VARCHAR(500)) AS DZDINDEX, "        //定值單編號
33                         + "CAST(T1.BRANCHID AS VARCHAR(500)) AS BRANCHID, "//版本
34                         + "CAST(@NAME2 AS VARCHAR(500)) + "
35                         + "CAST(@NAME3 AS VARCHAR(500)) AS ENDTIME1, "
36                         + "CAST(@NAME5 AS VARCHAR(500)) + "
37                         + "CAST(@NAME6 AS VARCHAR(500)) AS ENDTIME2 " ); 
38                 sql.append(" FROM ");
39                 sql.append( " US_APP.TB_DZD_INFORMATION T1, ");
40                 sql.append(" US_SYS.TV_WF_TASKLOG T, ");
41                 sql.append(" US_SYS.JBPM_VARIABLEINSTANCE V  ");
42                 sql.append(" WHERE ");
43                 sql.append("T1.ISDELETE = 0 ");
44                 sql.append(" AND T1.GUID = V.STRINGVALUE_ ");
45                 sql.append(" AND T.PROCESSINSTANCE = V.PROCESSINSTANCE_ ");
46                 sql.append(" AND (T.TASKNAME = '執行' ) ");
47                 sql.append(" AND T1.GUID = ? " );   
48                 dataTablec = genericDao.getDataIntoDataTable(sql.toString(), new Object[]{guida[j],guida[j]});
49                 dataTable.appendRow(dataTablec.getRow(0));

 

 2將信息導出為datatable格式(公司框架)

這樣查出了信息之後其實也順便將信息放入一個datatable中了,這個datatable好像是c#中的一種封裝好的, 公司平臺也給它用java封裝了一個類。

這樣每個datatable中其實包含了一個sheet的信息,一會對這個對象進行上下的迴圈遍歷就能夠存入信息主體啦。

說的很輕鬆他媽的看這個datatable的源碼看了我好久,太菜了。

 

3將datatable格式轉化為workbook(迴圈遍歷)

這樣是一個sheet,使用poi 包可以通過建立一個workbook(一個完整的excel表格)

我是這樣做的,就是先在迴圈外圍建立一個workbook,然後在sub迴圈中建立sheet,guid迴圈,也就建立了sub.length個sheet,一個sheet中也包含了一個sub中的所有信息,這個work中包含了所有全部sheet。  (sheet的name就是查詢出的subname)

 W

 我是不是搞複雜了。。。

 

 4workbook生成多SHEET以及合併單元格,單元格賦值,轉換style

到這裡就是一個比較繁瑣的事情了,因為在需求中有五種格式一上,還有單元格的樣式問題。

先說sheet導入時單個sheet其實是這個樣子(下麵是樣式),有特別多不符合要求的地方,這裡還沒有分sheet,此刻就先讓整個數據信息向下平移兩個單元格留出標題以及序號的位置,然後向右平移留出一個序號位置。

 

 具體工具類的設定就不說了,比較簡單。

重點說一下合併單元格以及合併單元格的賦值與設定cellstyle是如何操作的。

下麵的代碼就是先使用這個合併單元格,

 CellRangeAddress(起始行,結束行,起始列,結束列);
CellRangeAddress craa = new CellRangeAddress(rownumber,rownumber,0,5);

像我這樣創建的話,這個單元格就是rownumber的第一個單元格了,因為起始列是0.
但是現在其實sheet中並沒有改變這個單元格。
必須要用
 sheet.addMergedRegion(craa); 
這個語句來進行sheet單元格的添加。
添加後,需要
    HSSFRow roww = sheet.createRow(rownumber);
  HSSFCell cellw = roww.createCell((short)0);

在sheet中找到對應行以及對應單元格位置。以上。 這樣,單元格與合併單元格就對應啦。

就可以和正常單元格一樣給它賦值設定style或是乾什麼了~~~。

下麵代碼,沒有格式,我在下麵會加上所有代碼。
 1     int rownumber = dataRows.size()+3 ;
 2                 HSSFRow roww = sheet.createRow(rownumber);
 3                 HSSFRow rowwq = sheet.createRow(rownumber+1);
 4                 roww.setHeight((short) 600);// 設定行的高度
 5                 roww.setRowStyle(cellStyle);
 6                 rowwq.setHeight((short) 600);// 設定行的高度
 7                 rowwq.setRowStyle(cellStyle);
 8                 CellRangeAddress craa = new CellRangeAddress(rownumber,rownumber,0,5);
 9                 CellRangeAddress craaa = new CellRangeAddress(rownumber,rownumber,6,12);
10                 CellRangeAddress craab = new CellRangeAddress(rownumber+1,rownumber+1,0,5);
11                 CellRangeAddress craabb = new CellRangeAddress(rownumber+1,rownumber+1,6,12);
12                 sheet.addMergedRegion(craa); 
13                 HSSFCell cellw = roww.createCell((short)0);
14                 cellw.setCellValue("繼保整定核對日期及核對人:");
15                 sheet.addMergedRegion(craaa); 
16                 HSSFCell celle = roww.createCell((short)6);
17                 celle.setCellValue("變電運行核對日期及核對人:");
18                 sheet.addMergedRegion(craab); 
19                 HSSFCell cellr = rowwq.createCell((short)0);
20                 cellr.setCellValue("調度核對日期及核對人:");
21                 sheet.addMergedRegion(craabb); 
22                 HSSFCell cellt = rowwq.createCell((short)6);
23                 cellt.setCellValue("檢修繼保班核對日期及核對人:");
24                 int rowss = dataRows.size() + 5;    //rowss為datatable行數
25                 HSSFRow rowq = sheet.createRow(rowss);//sheet創建行
26                 rowq.setHeight((short) 300);// 設定行的高度
27                 rowq.setRowStyle(cellStyle);
28                 CellRangeAddress cra=new CellRangeAddress(rowss,rowss+10,0,columns.size()-1);//合併單元格的首行、最後一行、首列、最後一列。
29                 sheet.addMergedRegion(cra); 
30                 HSSFCell cellq = rowq.createCell((short)0);
31                 cellq.setCellValue(Constants.CHECKMANAGEMENT_CHECKDZDSTANDARD);
32                 cellq.setCellStyle(cellStyley);
33                 cellw.setCellStyle(cellStyleq);
34                 celle.setCellStyle(cellStyleq);
35                 cellr.setCellStyle(cellStyleq);
36                 cellt.setCellStyle(cellStyleq);
37                 CellRangeAddress crm = new CellRangeAddress(0,0,0,columns.size()-1);//表頭大標題
38                 HSSFRow rowm = sheet.createRow(0);//sheet創建行
39                 rowm.setHeight((short) 1000);// 設定行的高度
40                 rowm.setRowStyle(cellStylem);
41                 sheet.addMergedRegion(crm);
42                 HSSFCell cellm = rowm.createCell((short)0);
43                 cellm.setCellValue("台州電網繼電保護及安全自動裝置整定單核對錶");
44                 cellm.setCellStyle(cellStylem);
合併單元格賦值
 1     int rownumber = dataRows.size()+3 ;
 2                 HSSFRow roww = sheet.createRow(rownumber);
 3                 HSSFRow rowwq = sheet.createRow(rownumber+1);
 4                 roww.setHeight((short) 600);// 設定行的高度
 5                 roww.setRowStyle(cellStyle);
 6                 rowwq.setHeight((short) 600);// 設定行的高度
 7                 rowwq.setRowStyle(cellStyle);
 8                 CellRangeAddress craa = new CellRangeAddress(rownumber,rownumber,0,5);
 9                 CellRangeAddress craaa = new CellRangeAddress(rownumber,rownumber,6,12);
10                 CellRangeAddress craab = new CellRangeAddress(rownumber+1,rownumber+1,0,5);
11                 CellRangeAddress craabb = new CellRangeAddress(rownumber+1,rownumber+1,6,12);
12                 sheet.addMergedRegion(craa); 
13                 HSSFCell cellw = roww.createCell((short)0);
14                 cellw.setCellValue("繼保整定核對日期及核對人:");
15                 sheet.addMergedRegion(craaa); 
16                 HSSFCell celle = roww.createCell((short)6);
17                 celle.setCellValue("變電運行核對日期及核對人:");
18                 sheet.addMergedRegion(craab); 
19                 HSSFCell cellr = rowwq.createCell((short)0);
20                 cellr.setCellValue("調度核對日期及核對人:");
21                 sheet.addMergedRegion(craabb); 
22                 HSSFCell cellt = rowwq.createCell((short)6);
23                 cellt.setCellValue("檢修繼保班核對日期及核對人:");
24                 int rowss = dataRows.size() + 5;    //rowss為datatable行數
25                 HSSFRow rowq = sheet.createRow(rowss);//sheet創建行
26                 rowq.setHeight((short) 300);// 設定行的高度
27                 rowq.setRowStyle(cellStyle);
28                 CellRangeAddress cra=new CellRangeAddress(rowss,rowss+10,0,columns.size()-1);//合併單元格的首行、最後一行、首列、最後一列。
29                 sheet.addMergedRegion(cra); 
30                 HSSFCell cellq = rowq.createCell((short)0);
31                 cellq.setCellValue(Constants.CHECKMANAGEMENT_CHECKDZDSTANDARD);
32                 cellq.setCellStyle(cellStyley);
33                 cellw.setCellStyle(cellStyleq);
34                 celle.setCellStyle(cellStyleq);
35                 cellr.setCellStyle(cellStyleq);
36                 cellt.setCellStyle(cellStyleq);
37                 CellRangeAddress crm = new CellRangeAddress(0,0,0,columns.size()-1);//表頭大標題
38                 HSSFRow rowm = sheet.createRow(0);//sheet創建行
39                 rowm.setHeight((short) 1000);// 設定行的高度
40                 rowm.setRowStyle(cellStylem);
41                 sheet.addMergedRegion(crm);
42                 HSSFCell cellm = rowm.createCell((short)0);
43                 cellm.setCellValue("台州電網繼電保護及安全自動裝置整定單核對錶");
44                 cellm.setCellStyle(cellStylem);

   

    然後序號問題我就做的比較蠢了,向下平移兩格後第二行我直接設置column.size()的個數遞增設置列序號。。。。。。。

   豎向序號的話就直接在資料庫中加了點東西,因為用的是sql server,所以有現成的東西。

ROW_NUMBER() OVER (ORDER BY GUID) AS 'RowNumber'
這個可以增加行序號~

5生成workbook後  彈出下載頁面  能夠傳到瀏覽器界面提供下載   (有關springweb框架前後臺傳參數取值問題 )

   有關這個前後臺傳遞參數的問題我搞了三天吧,從最開始傻了吧唧直接指定固定位置後臺直接保存,到前臺傳遞參數後臺接受並操作,操作後response回前臺彈出視窗併進行下載。問別人問到他煩哈哈哈哈哈媽的真是沒愛。

 1 var openPostWindow = function(url,params){
 2        debugger
 3        var form = $("<form>");
 4        form.attr("style","display:none");                //    not success
 5        form.attr("action", url);
 6        form.attr("target","_blank");                      //    not success
 7        form.attr("method","post");
 8        form.attr("action",url);
 9        for(var param in params){
10            var inputField = $("<input>");
11            inputField.attr("type","text");
12            inputField.attr("name",param);
13            inputField.attr("value",params[param]);
14            form.append(inputField);                  //把參數值以表單形式傳遞   !!   獲取參數值
15        }
16        $("body").append(form);
17        form.submit();
18        form.remove();
19        
20    }
傳參

 

 

      首先,所用框架決定,我要是想彈出下載的話,應該有固定的參數格式。我的參數格式是參照springweb傳遞參數的格式設定的。這裡就不是java的問題了,是js jq的問題,他們應當能夠給我後臺傳回我所需要我能操作的參數。

     這裡貼一段js代碼。前臺單擊按鈕,首先將要獲取的東西一一獲取,然後設定url,然後設定參數,然後提交到openpostwindow中,在這個方法裡面,新建一個form表單,傳過來幾個參數,我就新建幾個inputfield ,不過這些都是隱藏著進行的,用戶看不到,然後使用for in  依次給inputfield賦值,name和value,皆對應相應的參數值,

比如我的,就是name就是我自己傳過來設定的那個名字,substationa

                   value則是我subtation實際傳過來的值,即"白雲變"

這樣 ,form中包含著三個inputfield,而這三個控制項則擁有其自己的名字和值,  然後進行提交表單,就可以進入後臺,後臺中是這樣的定義的。

1 public String cdzdExcel(@RequestParam(value ="substationaa" , required = false) String substationaa,
2             @RequestParam(value ="voltageaa", required = false)String voltageaa,
3             @RequestParam(value ="guid", required = false) String guid
4             ) {

   這樣,就ok啦,前臺獲取的參數,通過提交表單,傳入後臺參數,後臺可以對這個進行操作了。required = false 是傳入的參數可以為空的意思~~~  

   這個應該算是註解模式吧,使用的時候必須debug慢慢看,前後臺都要debug,不然不行。

   調試這個時候總是要出現  error400的   ,不是你的url有問題,就是你的傳參有問題,一般我都是傳參有問題。

 1 {
 2                 type:"button",
 3                 text :"生成",
 4                 iconCls : 'icon-plus-circle',
 5                 csstype : 'primary',//背景色
 6                 onClick:function(){
 7                     var voltagea = F1WidgetMgr.get('voltage').getText();//獲取下拉框內電壓參數
 8                     var substationa = F1WidgetMgr.get('substation').getText();//獲取變電站參數
 9 //                    $('#grid').bpgrid('exportExcel');
10                     var rows = $("#grid").bpgrid('getSelected');//bdz?        
11                         if(rows.length == 0){
12                              artDialog.alert("請選擇數據進行操作!");
13                              return;
14                         }
15                     var valueForme = [];
16                     var i = 0;
17                     for(i;i<=(rows.length-1);i++){
18                         valueForme.push(rows[i].GUID);
19                     }
20                     var valueFormm = valueForme.toString();//將valueform轉為字元串比較容易轉入後臺
21 //                    alert(substationa);                        要是有太多需要生成就直接把頁數調成
22                     var url = "checkManagement/cdzdExcel/importsExcel.do";
23 //                    var url = "ui/grid/export.do";把valueForm
24 //                    
25 //                    var options = $('#gridpanel').data().f1Searchgrid.options;
26 //                    var params = {
27 //                            service : options.service,
28 //                            filterStr : options.filterStr
29 //                            
30 //                    }
31                     
32                     var params = {
33                             substationaa : substationa,
34                             voltageaa : voltagea,
35                             guid    : valueFormm
36                     };
37                     openPostWindow(url,params);
38                     
39 //                    alert("11");
 1 var openPostWindow = function(url,params){
 2        debugger
 3        var form = $("<form>");
 4        form.attr("style","display:none");                //    no success
 5        form.attr("action", url);
 6        form.attr("target","_blank");                      //    no success
 7        form.attr("method","post");
 8        form.attr("action",url);
 9        for(var param in params){
10            var inputField = $("<input>");
11            inputField.attr("type","text");
12            inputField.attr("name",param);
13            inputField.attr("value",params[param]);
14            form.append(inputField);                  //把參數值以表單形式傳遞   !!   獲取參數值
15        }
16        $("body").append(form);
17        form.submit();
18        form.remove();
19        
20    }

 

  前後臺傳參結束了,後臺操作也結束了,現在生成的這個workbook放到哪裡呢。~~~

    這麼放,重點看幾行,

  OutputStream out = response.getOutputStream();
20             response.setCharacterEncoding("UTF-8");
21             response.setContentType("application/x-msdownload");//設置向瀏覽器端傳送的文件格式
22             response.setHeader("Content-disposition", "attachment; filename="
23                     + URLEncoder.encode(fileName, "utf-8"));

 

22+23行代碼就是關鍵,以這個格式設置的話,便會彈出下載。  寫完記得關文件流。

這個代碼還存到了c盤,如果沒有c盤還會報錯。

 不想存的話可以直接刪了。

 1 /** 獲取excel數據 */
 2         HSSFWorkbook workbook = CdzdsuperImportExcelServiceImpl.getExcel(guidd,sub,userModel);
 3         /** 輸出流文件 */
 4         HttpServletResponse response = (HttpServletResponse) ThreadLocalUtils
 5                 .getObjectFromThreadLocal("response");
 6         try {
 7             // 表名
 8             String tableName =  "變電站定值單三核對錶";
 9             String path = "c:\\";
10             SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
11             Date date = new Date();
12             String formatDate = sdf.format(date);
13             // 文件名
14             String fileName =  formatDate + "年"+voltageaa + substationaa + tableName 
15                     + ".xls";
16             path += fileName;
17             FileOutputStream fileOut = new FileOutputStream(path); 
18             response.reset();
19             OutputStream out = response.getOutputStream();
20             response.setCharacterEncoding("UTF-8");
21             response.setContentType("application/x-msdownload");//設置向瀏覽器端傳送的文件格式
22             response.setHeader("Content-disposition", "attachment; filename="
23                     + URLEncoder.encode(fileName, "utf-8"));
24             workbook.write(fileOut); 
25             fileOut.flush();
26             fileOut.close();
27             workbook.write(out); 
28             out.flush();
29             out.close();
30         } catch (Exception e) {
31             throw new MessageException("下載出現錯誤", e);
32         }
33         return json.toJson(new ValidateMessage(true, "111"));

 

(五)總結

這個是我自己做出來的效果。代碼會在下麵。

 總結

現在是總結和吐槽時間。

這個功能其實想想不難,難住我的是剛接觸java直接用框架再加上公司平臺,我直接懵逼,期間自我否定,有點怨天尤人,讓我耽誤了很多時間。

剛開始我是真的覺得自己做不出來,幾乎什麼都不懂,然後這個功能身邊一個組的同事也都不太懂。。。我問人都沒地方問。。。真的太折磨了。。。

資料庫由於應用不熟練不懂游標 ,一路查一路搞過來,資料庫應該註意的是在java語句中一定要註意空格,註意一些字元的長度,我被guid坑了好久,因為預設字元長度太短我的guid總是少了兩個字元,找了好久查詢不出來的問題。游標懂了一些,拼接懂了一點,表的聯合懂了一點。

前後臺那裡問人加研究,debug太重要了,一步一步,de的我頭髮嘩嘩掉。

poi操作excel ,我從聽都沒聽過到做出這麼一個比較規整美觀的表格我還是很有成就感的,多虧了博客園的諸多博客以及百度啦,需要改進的地方就是自己不太想去深入的理解,總是去試,因為這樣不用思考,這樣太蠢了,,100多個嘗試文檔。。也是智障。。。。

 

最重要的是,做事絕不可以敷衍了事了,工作不滿足用戶需求,就是你自己的鍋,活在手裡,決不能逃避,逃也是你的,不會做還是你的,沒有人會管你。

凡事先debug再問人,先把手裡信息弄懂,這樣問人,別人說的話你才懂,你問別人的問題,才有分量。

時間不等人,努力。。。。

以下為各層代碼

 1 package com.jb.f1.checkManagement.taizhou.controller;
 2 import java.io.FileOutputStream;
 3 import java.io.OutputStream;
 4 import java.net.URLEncoder;
 5 import java.text.SimpleDateFormat;
 6 import java.util.ArrayList;
 7 import java.util.Date;
 8 import java.util.List;
 9 
10 import javax.annotation.Resource;
11 import javax.servlet.http.HttpServletResponse;
12 import javax.servlet.http.HttpSession;
13 
14 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
15 import org.springframework.stereotype.Controller;
16 import org.springframework.web.bind.annotation.RequestMapping;
17 import org.springframework.web.bind.annotation.RequestParam;
18 import org.springframework.web.bind.annotation.ResponseBody;
19 
20 import com.jb.core.constant.ICnsView;
21 import com.jb.data.DataTable;
22 import com.jb.exception.MessageException;
23 import com.jb.f1.checkManagement.taizhou.service.impl.CdzdImportExcelServiceImpl;
24 import com.jb.f1.kernel.util.ThreadLocalUtils;
25 import com.jb.model.UserModel;
26 import com.jb.util.json.JsonBinder;
27 import com.jb.workflow.data.ValidateMessage;
28 /**
29  * 
30  * @author zyb
31  *2016年8月25日
32  *com.jb.f1.checkManagement.taizhou.controller
33  */
34 
35 @Controller
36 @RequestMapping("/cdzdExcel")
37 public class CdzdsuperImportExcelController {
38     @Resource(name = "CdzdsuperImportExcelServiceImpl")
39     private com.jb.f1.checkManagement.taizhou.service.impl.CdzdsuperImportExcelServiceImpl CdzdsuperImportExcelServiceImpl ;
40     /** 轉換器 */
41     protected JsonBinder json = JsonBinder.getJsonBinder();
42     @RequestMapping("importsExcel.do")
43     @ResponseBody
44     public String cdzdExcel(@RequestParam(value ="substationaa" , required = false) String substationaa,
45             @RequestParam(value ="voltageaa", required = false)String voltageaa,
46             @RequestParam(value ="guid", required = false) String guid
47             ) {
48         HttpSession session = (HttpSession) ThreadLocalUtils.getObjectFromThreadLocal("session");    
49         UserModel userModel = (UserModel) session.getAttribute(ICnsView.LOGIN_USERMODEL);
50          String[] guidd =new String[]{};
51          guidd = guid.split(",");  //轉換為字元數組
52          String guiddd = "'"+guid.replaceAll(",", "','")+"'";//轉換為能夠被數據查詢語句查詢的字元串
53          List sublist = new ArrayList();
54          String[] sub =new String[]{};
55          //1  guid獲取sublist
56          sublist = CdzdsuperImportExcelServiceImpl.getSubName(guiddd);
57          String[] array =new String[sublist.size()];
58          sub = (String[]) sublist.toArray(array);//  字元數組
59           //2  guidd  sub  這兩個返回workbook
60         /** 獲取excel數據 */
61         HSSFWorkbook workbook = CdzdsuperImportExcelServiceImpl.getExcel(guidd,sub,userModel);
62         /** 輸出流文件 */
63         HttpServletResponse response = (HttpServletResponse) ThreadLocalUtils
64                 .getObjectFromThreadLocal("response");
65         try {
66             // 表名
67             String tableName =  "變電站定值單三核對錶";
68             String path = "c:\\";
69             SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
70             Date date = new Date();
71             String formatDate = sdf.format(date);
72             // 文件名
73             String fileName =  formatDate + "年"+voltageaa + substationaa + tableName 
74                     + ".xls";
75             path += fileName;
76             FileOutputStream fileOut = 
              
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 原因: 因為在網上下載視頻教程,有的名字特別長,一般都是機構或者網站的宣傳,不方便直接看到視頻的簡介,所以做了下麵的第一個功能。 因為老師發的課件中,文件夾太多,想把docx都放在同一個文件夾下麵,一個一個找出來太麻煩,所以做了第二個功能。 最近剛剛學了Java文件和流的知識,所以正好練練手,這也是 ...
  • 搞了個簡單的Excel導入, 用的是PHPExcel(百科:用來操作Office Excel文檔的一個PHP類庫, 基於微軟的OpenXML標準和PHP語言) 好, 不說了, 開始吧... 首先得有PHPExcel類庫, 點這裡下載 https://github.com/Zmwherein/PHPE ...
  • ...
  • 序列(sequence)【題目描述】蛤布斯有一個序列,初始為空。它依次將 1-n 插入序列,其中 i插到當前第 ai 個數的右邊 (ai=0 表示插到序列最左邊)。它希望你幫它求出最終序列。【輸入數據】第一行一個整數 n。第二行 n 個正整數 a1~an。【輸出數據】輸出一行 n 個整數表示最終序列... ...
  • 由於使用DriverManager獲取資料庫連接時,由於DriverManager實現類中有一段靜態代碼塊,可以直接註冊驅動,且可以同時管理多個驅動程式 所以當換資料庫連接時需要指定不同的資料庫,那麼就需要反覆修改properties配置文件(雖然並不麻煩),所以我想將每種驅動連接程式的proper ...
  • 數組對每門編程語言都是重要的數據結構之一,java語言提供的數組是用來儲存固定大小的同類型元素的。 當你需要保存一組數據類型相同的變數或者對象時,我們不可能給每個變數都定義一個變數名,這樣的操作會使代碼臃腫、工作量大且無意義。這時我們就需要數組來保存這些數據。數組根據需要的不同分為一維數,二維數組和 ...
  • 先看一下文件,在當前包下有一個properties配置文件,在根目錄下有一個lib文件夾,裡面放的是mySql的驅動jar包 Driver :是一個介面,資料庫廠商必須提供實現的介面,能從其中獲取資料庫連接 可以通過Driver的實現類的對象獲取資料庫連接 * 1.加入mySql驅動 * 1.1 解 ...
  • 一、MyBaris簡介 1)MyBaris發展過程 MyBatis的前身叫iBatis,本是apache的一個開源項目, 2010年這個項目由apache software foundation 遷移到了google code,並且改名為MyBatis。 MyBatis是支持普通SQL查詢,存儲過程 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...