起因:項目需要一個可以固定列和表頭的表格,因為表格要顯示很多列,當水平滾動條拉至后邊時可能無法看到前邊的某些信息。
以前在angularjs 1.x 中一直都是直接 ng-repeat去完成一個table,顯示上沒有太多要求,此時遇到這個需求 ,時間上又無法允許你去思考實現之法,而且angularjs 去實現一個像這樣的指令也並不容易,於是便要去尋找一個可用的angularjs 插件。
Angular UI-Grid ui-grid.info
同以往的js插件一樣,可以通過 bower ,npm 等 獲取。
1 <section ui-grid="gridOptions" ui-grid-exporter ui-grid-pagination ui-grid-grouping ui-grid-selection ui-grid-auto-resize ui-grid-pinning ui-grid-resize-columns class="grid"></section>
UI-Grid 使用了一些directive 去實現相應的功能 :
ui-grid-exporter 用於數據導出
ui-grid-pagination 用於啟用分頁
ui-grid-grouping 用於啟用數據分組
ui-grid-selection 用於啟用選擇行
ui-grid-auto-resize 用於啟用高度自適應
ui-grid-pinning 用於固定列
ui-grid-resize-columns 用於拖動列寬度
那么要用到這些指令我們需要將一寫Module導入到自己的應用中.在我的app.js 中:
1 angular.module('exampleApp', [ 2 'ui.grid', 3 'ui.grid.pinning', 4 'ui.grid.pagination', 5 'ui.grid.selection', 6 'ui.grid.autoResize', 7 'ui.grid.resizeColumns', 8 'ui.grid.exporter', 9 'ui.grid.grouping' 10 ]);
導入之后還需要對grid 進行一些配置
就是上邊的 gridOptions ,在我的controller中對它進行如下配置:
exporterMenuCsv:是否在Grid Meun中顯示Csv導出項,當啟用數據導出時,此配置默認為 true
gridMenuCustomItems:在Grid Menu中我們可以自定義自己的菜單項和對應的行為。
1 [ 2 { 3 title: '倒顯↙▼↙', 4 action: function ($event) { 5 this.grid.element.toggleClass('rotated'); 6 }, 7 order: 211 8 },{ 9 title: '導出Excel', 10 action: function ($event) { 11 var bdate = vm.startDate.val?moment(vm.startDate.val).format('YYYY-MM-DD'):''; 12 var edate = vm.endDate.val ?moment(vm.endDate.val).format('YYYY-MM-DD'):''; 13 var status = vm.selectedStatu.status; 14 var dtype = vm.querySummaryInput.dateType; 15 var lessexporturi = '/ConnBridge/ExportExcel4lessdata?begindate='+bdate+'&enddate=' 16 abp.openwin(lessexporturi); 17 }, 18 order: 210 19 } 20 ]
exporterMenuPdf :是否在Grid Menu 中顯示 導出Pdf的選項 ,在啟用Pdf的時候需要一些其他的操作,下邊在說。
enablePagination:是否啟用默認分頁,默認為 true
enablePaginationControls:使用底部的默認分頁.
paginationPageSizes:頁容量的可選值
paginationCurrentPage:頁碼
paginationPageSize:頁容量
totalItems:數據總條數
useExternalPagination:是否使用分頁按鈕
exporterFieldCallback:導出數據之前的操作,可以進行導出數據格式化
enableGridMenu:是否啟用Grid Menu
exporterOlderExcelCompatibility:兼容Excel的Csv操作 ,后邊說詳細
showGridFooter:是否顯示Grid Footer
showColumnFooter:是否顯示Column Footer
enableRowHeaderSelection:是否顯示選擇行的第一列
exporterCsvFilename:需要導出的Csv的文件名稱.
exporterPdfDefaultStyle:需要導出的Pdf的默認樣式.
exporterPdfFilename:需要導出的Pdf的文件名稱.
exporterAllDataFn:當點擊導出所有數據時提供數據的方法.
enableHorizontalScrollbar:是否顯示水平滾動條. 0 為不顯示 1為顯示
enableVerticalScrollbar:是否顯示垂直滾動條. 0 為不顯示 1為顯示
onRegisterApi:分頁按鈕事件方法
name:可以用來和數據進行關聯,如果不提供應該提供 field以用來讓UI-Grid關聯數據
field:可以用來和數據進行關聯 field以用來讓UI-Grid關聯數據,和name的具體區別可以看Grid 文檔
displayName:顯示的列名稱
width:指定列寬度 可以用 * 或者** 自動適應 詳見文檔
rowHeight:行高度,默認是30
enablePinning:啟用固定列
pinnedLeft:固定到左側
pinnedRight:固定到右側
groupingShowAggregationMenu:是否在菜單中顯示分組計算
groupingShowGroupingMenu:是否在列表菜單中顯示分組
enableSorting:是否啟用排序
visible:是否隱藏列
cellFilter:列數據過濾器 可以應用 date,number ...還有自定義的filter
aggregationType:分組數據顯示類型 這里可以計算總和,求平均值等 例如求和: uiGridConstants.aggregationTypes.sum並顯示在footer對應的column中
footerCellTemplate:可以自定義column footer的顯示模板
type:指定數據類型 應用於排序
在使用JS插件的時候,常常要考慮的問題是本地化,UI-Grid也不例外
在第一次未配置時候,或顯示亂碼 ,我們可以注入 i18nService服務來進行獲取或配置語言
i18nService.getAllLangs()可以獲取所有支持的語言.
i18nService.getCurrentLang()可以查看當前的語言.
這樣我們可以通過i18nService.setCurrentLang('zh-cn')可以設置為中文簡體
在使用Pdf導出的前提是要引入 pdfmake.min.js 和 vfs_fonts.js
但是當我導出這些數據的時候pdf會中文亂碼
解決辦法是重新生成 vfs_fonts.js 目的是把中文字體寫入此文件
首先我們要找到源代碼
mkdir mkpdf cd mkpdf git clone https://github.com/bpampuch/pdfmake.git
pdfmake下的examples中進入fonts文件夾,將我們的中文字體放入此文件夾中。
回到pdfmake文件夾,執行 npm install 確保所有依賴的包都已經安裝
之后 執行gulp buildFonts 生成 vfs_fonts.js 和(pdfmake.min.js pdfmake.js )
完成這些之后我們要做的是,將自己項目中的這些js文件 替換為 新生成的js文件。
在我們要導出pdf之前還要配置一下字體
1 window.pdfMake.fonts={ 2 simblack: { 3 normal: 'msyh.ttf', 4 bold: 'msyhbd.ttf', 5 italics: 'msyh.ttf', 6 bolditalics: 'msyh.ttf' 7 }, 8 Roboto: { 9 normal: 'Roboto-Regular.ttf', 10 bold: 'Roboto-Medium.ttf', 11 italics: 'Roboto-Italic.ttf', 12 bolditalics: 'Roboto-Italic.ttf' 13 } 14 }
這樣我們就可以在UI-Grid中配置我們想要使用的預定義字體 ,還記得上邊這個配置么 ?
exporterPdfDefaultStyle :{font:'simblack',fontSize: 9}
導出的Csv文件,Excel 打開亂碼
開發的時候因為本機一直安裝wps 所以打開一直沒問題,可是拿到別人的機器上用 office excel 2016 打開中文就會亂碼.
這個亂碼多是編碼問題,這樣我用記事本打開指定的Csv文件並用 ANSI 編碼 替換,中文便可以正常顯示
github 上找到這個問題 他們可以用這個屬性配置兼容 office excel 正確顯示中文 就是上邊提到的 這個配置 exporterOlderExcelCompatibility:true 這個配置默認是 false 的,需要我們自己啟用。
雖然 用 office excel 2016 打開不會亂碼了,但是我用 office excel 2007 打開問題依舊, 看樣子Csv文件做表格並不妥當.
后來 我干脆把前台的數據導出都移至后台,於是就出現了為什么要自定義Grid Menu 的需要 還有就是禁用菜單默認顯示的Csv文件導出。
Grid 雖好很多功能都實現的不錯,但是自己用的時候發現一些問題 :
1 . 當我開啟固定列時,如果沒有水平滾動條的話,那么當垂直滾動數據到底部的時候固定列的數據和后邊的數據行會對不齊。
2 . 當快速拉動滾動條(垂直或水平)時,表格會卡頓,數據顯示並不是十分流暢,這點我感覺是 UI-Grid 最悲催的問題,或許是我看問題的視角不夠廣,但是問題畢竟是問題。
當需要自定義Column Footer cell 的樣式和數據時 在 footerCellTemplate 中我們可以 用 grid.appScope 訪問 $scope 可以用 row 和 grid 去找我們想要的行 或者是grid 數據。
比如我之前的要的一個功能是在分組的那一行顯示一個按鈕用於跳轉 詳細頁面 ,那么首先我要確定 哪一行是 分組行,還要找到那一行"分組的文本"(例如按訂單編號分組,分組文本就是訂單編號) 。
1 .確定是不是分組那一行(或是聚合的那一行) 我們可以用 row.groupHeader===true 。
2. 找到分組文本(或是聚合文本) ,可以用 row.entity['$$uiGrid-0008'].groupVal 。
補充:
對於上邊的表格卡頓問題,之前沒有仔細閱讀文檔,在Grid-Options 的配置中可以用 columnVirtualizationThreshold :10 (列)和virtualizationThreshold:20 (行) 這兩個配置解決 ,我們可以將他們的值設置的大一些,就不會卡頓了。 O(∩_∩)O~~