<td id="mukkm"><td id="mukkm"></td></td>
  • <nav id="mukkm"></nav>
  • <nav id="mukkm"></nav>
     找回密碼
     注冊帳號

    掃一掃,訪問微社區

    Like Unity讀寫Excle表格(使用NPOI.dll)

    22
    回復
    14022
    查看
    打印 上一主題 下一主題
    [ 復制鏈接 ]
    排名
    64954
    昨日變化

    5

    主題

    54

    帖子

    1191

    積分

    Rank: 9Rank: 9Rank: 9

    UID
    354297
    好友
    0
    蠻牛幣
    477
    威望
    0
    注冊時間
    2020-11-3
    在線時間
    1126 小時
    最后登錄
    2022-8-17

    馬上注冊,結交更多好友,享用更多功能,讓你輕松玩轉社區。

    您需要 登錄 才可以下載或查看,沒有帳號?注冊帳號

    x
    【前言】
    之前接手一個同事的代碼時,發現其中有個項目用到了Excle,隨后就產生了興趣,想把這個常用的辦公軟件應用Unity,就利用空余時間研究了幾天。
    之前在技術群看到有人問過Excle如何讀寫,然后加了他好友后,他發了個不全的Excle插件給我,然后我發現很多報錯,就自己在百度娘哪里找了一個完整功能的Excle插件,歸根到底,他的底層邏輯也是基于NPOI的Dll文件來實現數據讀寫,所以我就總結了前任程序的代碼和網上的一些案例,寫了一個關于Excle讀寫的功能。
    多得也不說了,看一下我總結的成果吧。


    【準備工作】
    要準備NPOI的Dll文件,來為Unity做程序集調用。Dll文件我放入底下的碼云鏈接,可以在最后的話中點擊下載。



    【進入開發環節】

    1.新建一個結構體,作為保存玩家信息類型,注意要用[Serializable],方便能序列化到Inspector面板

    • [
    • public struct PData
    • {
    •     public string name_use;//用戶名
    •     public string number_phone;//手機號
    •     public string number_IDCard;//身份證號碼
    •     public string password;//用戶密碼
    • }




    2.Start方創建放置Json文件的目錄,以及我們設置的PData結構體數據寫入到Json中,然后用文件流寫入Excle表(其實這里多寫了一步Json的讀寫如果不需要Json保存各玩家數據的話,直接用結構體寫入Excle)

    • void Start()
    • {
    •     path_pData = Application.streamingAssetsPath +\\\"PData.xlsx\\\";//Excle表和位置Application.dataPath不能在創建成員變量時使用
    •     try
    •     {
    •         string path_json = Application.dataPath + \\\"Json\\\";
    •         if (Directory.Exists(path_json) == false)
    •         {
    •             Directory.CreateDirectory(path_json);
    •             print(\\\"creatPath\\\");
    •         }
    •     }
    •     catch (Exception ex)
    •     {
    •         print(\\\"創建文件異常:\\\" + ex);
    •         //throw;
    •     }
    •     try
    •     {
    •         //print(pDatas.Length);
    •         for (int i = 0; i < pDatas.Length; i++)//將PData所填寫的數據先寫入Json然后用文件流寫入Excle表(如果要改寫 pData現有的數據,要刪除對應的json文件增加長度則不用),其實這里沒必要,只是我多寫了一步Json的讀寫
    •         {
    •             if (File.Exists(Application.dataPath + \\\"/Json/user\\\" + i + \\\".json\\\") == false)
    •             {
    •                 FileStream fs = new FileStream(Application.dataPath + \\\"Json/user\\\" + i + \\\".json\\\" FileMode.Create);//創建json
    •                 byte[] bytes_write = System.Text.Encoding.GetEncoding(\\\"GB2312\\\").GetBytes(JsonMapper.ToJson(pDatas[i]));
    •                 fs.Write(bytes_write 0 bytes_write.Length);
    •                 fs.Close();
    •                 fs.Dispose();//文件流銷毀
    •                 print(\\\"creatJson\\\");
    •             }
    •         }
    •     }
    •     catch (Exception ex)
    •     {
    •         print(\\\"Json創建異常:\\\" + ex);
    •         //throw;
    •     }
    •     WriteExicle();//寫入exicle表
    •     ExicleToDataTable(\\\"Sheet1\\\"true);//從exicle寫入系統表中
    • }

    3.將結構體數據寫入Excle表格:遍歷Json文件夾的文件然后將所有保存不同玩家的信息反序列化成PData結構體(繞了一圈,參照第二條),然后設置單元格屬性之類的,最后根據玩家數量設置有幾行(實際上比玩家數量要多出一行來做菜單欄),然后在菜單欄設置每一列的類型。隨后逐行寫入玩家的數據。最后在StreamingAssets文件夾創建玩家信息統計的Excle表。

    • /// <summary>寫入Exicle的方法,如果要重新制定表格的布局,那么就要修改結構體和寫入規則 </summary>
    • void WriteExicle()
    • {
    •     DirectoryInfo directoryInfo = new DirectoryInfo(Application.dataPath+\\\"Json\\\");//在Json目錄下
    •     FileInfo[] fileInfos = directoryInfo.GetFiles(\\\"*.json\\\"SearchOption.TopDirectoryOnly);//在指向目錄的頂層目錄下獲取所有的json文件
    •     List<PData> list_pData = new List<PData>(fileInfos.Length);
    •     for (int i = 0; i < fileInfos.Length; i++)//把每個Json文件讀取出來放入數據列表list_pData
    •     {
    •         FileStream fileS = fileInfos[i].OpenRead();
    •         byte[] bytes_read = new byte[fileS.Length];
    •         fileS.Read(bytes_read0bytes_read.Length);
    •         fileS.Close();
    •         fileS.Dispose();
    •         list_pData.Add(JsonMapper.ToObject<PData>(System.Text.Encoding.UTF8.GetString(bytes_read)));//把json解析成結構體添加進列表中
    •     }
    •     HSSFWorkbook hssfw = new HSSFWorkbook();
    •     ISheet sheet = hssfw.CreateSheet(\\\"Sheet1\\\");
    •     sheet.SetColumnWidth(0512*10);//設置列寬
    •     sheet.SetColumnWidth(1 521 * 15);
    •     sheet.SetColumnWidth(2 512 * 20);
    •     sheet.SetColumnWidth(3 512 * 15);
    •     IRow row;//行類
    •     ICell cell;//單元格類        
    •     for (int i = 0; i <= list_pData.Count; i++)//用第一行來取標題,所以《=最大長度
    •     {
    •         row = sheet.CreateRow(i);
    •         for (int j = 0; j < 4; j++)
    •         {
    •             cell = row.CreateCell(j);
    •             //設置表格的樣式
    •             ICellStyle  = hssfw.CreateCellStyle();
    •             .BorderBottom = BorderStyle.Thin;
    •             .BorderLeft = BorderStyle.Thin;
    •             .BorderRight = BorderStyle.Thin;
    •             .BorderTop = BorderStyle.Thin;
    •             .Alignment = HorizontalAlignment.Left;
    •             cell.CellStyle = ;
    •             if(i == 0)//第一行取標題
    •             {
    •                 switch (j)
    •                 {
    •                     case 0:
    •                         cell.SetCellValue(\\\"用戶名\\\");
    •                         break;
    •                     case 1:
    •                         cell.SetCellValue(\\\"手機號\\\");
    •                         break;
    •                     case 2:
    •                         cell.SetCellValue(\\\"身份證號碼\\\");
    •                         break;
    •                     case 3:
    •                         cell.SetCellValue(\\\"用戶密碼\\\");
    •                         break;
    •                     default:
    •                         break;
    •                 }
    •             }
    •             else
    •             {
    •                 switch (j)
    •                 {
    •                     case 0:
    •                         cell.SetCellValue(list_pData[i-1].name_use);//i需要減1,保證不超出范圍
    •                         break;
    •                     case 1:
    •                         cell.SetCellValue(list_pData[i-1].number_phone);
    •                         break;
    •                     case 2:
    •                         cell.SetCellValue(list_pData[i-1].number_IDCard);
    •                         break;
    •                     case 3:
    •                         cell.SetCellValue(list_pData[i-1].password);
    •                         break;
    •                     default:
    •                         break;
    •                 }
    •             }                    
    •         }
    •     }
    •     if (Directory.Exists(Application.dataPath + \\\"/StreamingAssets\\\") == false)
    •     {
    •         Directory.CreateDirectory(Application.dataPath + \\\"/StreamingAssets\\\");
    •         print(\\\"streamingAssets創建成功\\\");
    •     }
    •     FileStream fs = new FileStream(path_pData FileMode.OpenOrCreate);
    •     hssfw.Write(fs);
    •     //byte[] bytes = new byte[fs.Length];
    •     //fs.Read(bytes0bytes.Length);
    •     //print(System.Text.Encoding.UTF8.GetString(bytes));     
    •     fs.Close();
    •     fs.Dispose();
    •     //ExicleToDataTable(\\\"Sheet1\\\" true);
    • }//寫入exicle中


    4.將Exicle數據轉讀取存入DataTable中:首先找到表格位置,轉換成文件流,然后根據Exicle版本創建workbook,然后獲取工作單sheet,然后在工作單中數據返回到DataTable中,根據行列來獲取DataTable中的元素。

    • /// <summary>
    • /// 將Exicle數據轉存入DataTable中
    • /// </summary>
    • /// <param name=\\\"sheelName\\\">工作薄的名字</param>
    • /// <param name=\\\"isFirstRowColumn\\\">第一行是否是DataTable的列名</param>
    • /// <returns>返回的dataTable</returns>
    • DataTable ExicleToDataTable(string sheelName bool isFirstRowColumn)
    • {
    •     dataTable.Clear();
    •     ISheet sheet = null;        
    •     int startRow = 0;//開始行
    •     try
    •     {
    •         fs = new FileStream(path_pData FileMode.Open FileAccess.Read);
    •         IWorkbook workbook = null;
    •         if (path_pData.IndexOf(\\\".xlsx\\\") > 0)//2007
    •         {
    •             print(\\\"2007版本的Exicle\\\");
    •             workbook = new HSSFWorkbook(fs);
    •             fs.Close();
    •             fs.Dispose();
    •         }
    •         else if (path_pData.IndexOf(\\\".xls\\\") > 0)//2003版本的
    •         {
    •             //print(path_pData.IndexOf(\\\".xls\\\"));
    •             print(\\\"2003版本的Exicle\\\");
    •             workbook = new HSSFWorkbook(fs);
    •             fs.Close();
    •             fs.Dispose();
    •         }
    •         if (sheelName != null)
    •         {
    •             sheet = workbook.GetSheet(sheelName);//找到對應的工作單賦值
    •             if (sheet == null)//如果該名稱的工作單不存在
    •             {
    •                 sheet = workbook.GetSheetAt(0);//賦給第一張工作單
    •             }
    •         }
    •         else//如果該名稱為空
    •         {
    •             sheet = workbook.GetSheetAt(0);//賦給第一張工作單
    •         }
    •         if (sheet != null)
    •         {
    •             IRow firstRow = sheet.GetRow(0);
    •             int count_cell = firstRow.LastCellNum;//一行最后一個cell的編號 即總的列數
    •             if (isFirstRowColumn)
    •             {
    •                 for (int i = firstRow.RowNum; i < count_cell; i++)//處理第一行的所有單元格
    •                 {
    •                     ICell cell = firstRow.GetCell(i);
    •                     if (cell != null)
    •                     {
    •                         string callValue = cell.StringCellValue;//到這里已經能取到表格的數據了
    •                         print(callValue);//列的名字
    •                         if (callValue != null)//把第一行的所有標題添加進dataTable中
    •                         {
    •                             DataColumn column = new DataColumn(callValue);
    •                             dataTable.Columns.Add(column);
    •                         }
    •                     }
    •                 }
    •                 startRow = sheet.FirstRowNum + 1;//由于第一行是數據類型,所以數據要從第二行開始算
    •             }
    •             else//如果不需要第一行菜單欄
    •             {
    •                 startRow = sheet.FirstRowNum;
    •             }
    •             int count_row = sheet.LastRowNum;
    •             for (int i = startRow; i <= count_row; i++)//添加所有的表格數據
    •             {
    •                 DataRow dataRow = dataTable.NewRow();//new一個數據行
    •                 IRow row = sheet.GetRow(i);
    •                 if (row == null) continue;                    
    •                 for (int j = row.FirstCellNum; j < row.LastCellNum; j++)
    •                 {                        
    •                     if (row.GetCell(j) != null)
    •                     {
    •                         dataRow[j = row.GetCell(j).ToString();
    •                         print(row.GetCell(j).ToString());//獲取單元格的文本內容
    •                     }
    •                 }
    •                 dataTable.Rows.Add(dataRow);
    •             }
    •         }
    •         print(dataTable.Rows.Count);
    •         return dataTable;
    •     }
    •     catch (Exception ex)
    •     {
    •         print(\\\"捕獲異常:\\\" + ex);
    •         return null;
    •     }        
    • }


    【最后想說】
    寫專欄不易,且行且珍惜,附上碼云鏈接:https://gitee.com/likeji/unity-read--write---excel-data.git;這個資源的demo我只展示了Excle數據的讀取、查詢,用的是ExicleToDataTable()方法,如果要把數據寫入Excle表,那么就要在Start調用WriteExicle()方法。




    回復

    使用道具 舉報

    排名
    64954
    昨日變化

    5

    主題

    54

    帖子

    1191

    積分

    Rank: 9Rank: 9Rank: 9

    UID
    354297
    好友
    0
    蠻牛幣
    477
    威望
    0
    注冊時間
    2020-11-3
    在線時間
    1126 小時
    最后登錄
    2022-8-17
    沙發
    樓主 2020-11-11 09:44:21 只看該作者
    某些代碼由于粘貼過來時格式出現問題,老是修改不了,建議下載案例對比調試
    回復 支持 反對

    使用道具 舉報

    5熟悉之中
    981/1000
    排名
    6046
    昨日變化

    2

    主題

    53

    帖子

    981

    積分

    Rank: 5Rank: 5

    UID
    241177
    好友
    2
    蠻牛幣
    5867
    威望
    0
    注冊時間
    2017-9-3
    在線時間
    694 小時
    最后登錄
    2022-4-23
    板凳
    2020-11-11 10:14:18 只看該作者
    牛逼 收藏下
    回復

    使用道具 舉報

    5熟悉之中
    654/1000
    排名
    5137
    昨日變化

    3

    主題

    126

    帖子

    654

    積分

    Rank: 5Rank: 5

    UID
    217130
    好友
    0
    蠻牛幣
    1471
    威望
    0
    注冊時間
    2017-4-11
    在線時間
    253 小時
    最后登錄
    2020-11-11
    地板
    2020-11-11 15:56:01 只看該作者
    樓主666666666666666666666666
    回復 支持 反對

    使用道具 舉報

    7日久生情
    1673/5000
    排名
    3437
    昨日變化

    0

    主題

    983

    帖子

    1673

    積分

    Rank: 7Rank: 7Rank: 7Rank: 7

    UID
    210390
    好友
    0
    蠻牛幣
    1698
    威望
    0
    注冊時間
    2017-3-7
    在線時間
    256 小時
    最后登錄
    2021-1-11
    5#
    2020-11-11 17:26:18 只看該作者
    666666666666666666666666
    回復 支持 反對

    使用道具 舉報

    5熟悉之中
    693/1000
    排名
    8328
    昨日變化

    5

    主題

    265

    帖子

    693

    積分

    Rank: 5Rank: 5

    UID
    252298
    好友
    1
    蠻牛幣
    740
    威望
    0
    注冊時間
    2017-11-3
    在線時間
    277 小時
    最后登錄
    2022-2-15
    6#
    2020-11-12 10:49:36 只看該作者
    Plugin中dll缺失啦,只有文件了
    回復 支持 反對

    使用道具 舉報

    排名
    64954
    昨日變化

    5

    主題

    54

    帖子

    1191

    積分

    Rank: 9Rank: 9Rank: 9

    UID
    354297
    好友
    0
    蠻牛幣
    477
    威望
    0
    注冊時間
    2020-11-3
    在線時間
    1126 小時
    最后登錄
    2022-8-17
    7#
    樓主 2020-11-12 17:41:58 只看該作者
    q873438526 發表于 2020-11-12 10:49
    Plugin中dll缺失啦,只有文件了

    sourcetree好像上傳不了dll文件,我直接從碼云上傳了,下載康康吧
    回復 支持 反對

    使用道具 舉報

    排名
    64954
    昨日變化

    5

    主題

    54

    帖子

    1191

    積分

    Rank: 9Rank: 9Rank: 9

    UID
    354297
    好友
    0
    蠻牛幣
    477
    威望
    0
    注冊時間
    2020-11-3
    在線時間
    1126 小時
    最后登錄
    2022-8-17
    8#
    樓主 2020-12-7 20:03:06 只看該作者
    12-7日修改帖子格式,已經盡量減少發布帖子造成的字符串格式錯誤,對比源碼時盡量忽略“\\”樣式的錯誤
    回復 支持 反對

    使用道具 舉報

    0

    主題

    12

    帖子

    16

    積分

    Rank: 1

    UID
    355555
    好友
    0
    蠻牛幣
    9
    威望
    0
    注冊時間
    2020-12-21
    在線時間
    4 小時
    最后登錄
    2020-12-29
    9#
    2020-12-22 18:27:13 只看該作者
    mark一下
    回復

    使用道具 舉報

    7日久生情
    2047/5000
    排名
    3554
    昨日變化

    1

    主題

    478

    帖子

    2047

    積分

    Rank: 7Rank: 7Rank: 7Rank: 7

    UID
    203671
    好友
    2
    蠻牛幣
    4236
    威望
    0
    注冊時間
    2017-1-20
    在線時間
    1158 小時
    最后登錄
    2022-9-20
    10#
    2020-12-23 17:38:26 只看該作者
    6666666666666
    回復

    使用道具 舉報

    6蠻牛粉絲
    1088/1500
    排名
    3910
    昨日變化

    1

    主題

    146

    帖子

    1088

    積分

    Rank: 6Rank: 6Rank: 6

    UID
    68132
    好友
    7
    蠻牛幣
    1400
    威望
    0
    注冊時間
    2015-1-13
    在線時間
    577 小時
    最后登錄
    2022-2-22
    QQ
    11#
    2021-1-11 11:39:01 只看該作者
    樓主好人吶,期待更新word 讀寫
    回復 支持 反對

    使用道具 舉報

    排名
    48145
    昨日變化

    0

    主題

    16

    帖子

    84

    積分

    Rank: 2Rank: 2

    UID
    248854
    好友
    1
    蠻牛幣
    13
    威望
    0
    注冊時間
    2017-10-14
    在線時間
    64 小時
    最后登錄
    2021-2-23
    12#
    2021-1-19 15:56:29 只看該作者
    6666666666666666666666
    回復 支持 反對

    使用道具 舉報

    7日久生情
    3209/5000
    排名
    4162
    昨日變化

    19

    主題

    535

    帖子

    3209

    積分

    Rank: 7Rank: 7Rank: 7Rank: 7

    UID
    18541
    好友
    8
    蠻牛幣
    816
    威望
    0
    注冊時間
    2014-3-22
    在線時間
    2297 小時
    最后登錄
    2022-8-29
    13#
    2021-1-21 10:28:01 只看該作者
    秀啊 鉤子
    回復

    使用道具 舉報

    8常駐蠻牛
    5490/10000
    排名
    10703
    昨日變化

    0

    主題

    2345

    帖子

    5490

    積分

    Rank: 8Rank: 8

    UID
    301976
    好友
    1
    蠻牛幣
    5270
    威望
    0
    注冊時間
    2018-10-31
    在線時間
    3047 小時
    最后登錄
    2022-9-2
    14#
    2021-1-26 10:15:20 只看該作者
    可以的   
    回復 支持 反對

    使用道具 舉報

    2初來乍到
    132/150
    排名
    18289
    昨日變化

    0

    主題

    24

    帖子

    132

    積分

    Rank: 2Rank: 2

    UID
    174513
    好友
    0
    蠻牛幣
    196
    威望
    0
    注冊時間
    2016-10-12
    在線時間
    74 小時
    最后登錄
    2021-5-10
    15#
    2021-1-26 13:39:04 只看該作者
    樓主,好東西啊,牛逼666,
    回復 支持 反對

    使用道具 舉報

    您需要登錄后才可以回帖 登錄 | 注冊帳號

    本版積分規則

    關注游戲蠻牛公眾號送vip
    免费一级AA片毛片在线播放
    <td id="mukkm"><td id="mukkm"></td></td>
  • <nav id="mukkm"></nav>
  • <nav id="mukkm"></nav>