說實話 公司 閒着很無聊 不知道幹嗎 寫寫博客記錄一下html
環境搭建暫時很少說本人是使用本身的簡易腳手架搭建的,與excel無關的代碼不少,建議你們仍是使用本身搭建的腳手架好一點。這是個人github項目地址掘金Demo。自行百度
create-react-app
等官方推薦的腳手架吧。這裏只對excel核心功能進行講解。react
其實本人不太熟悉ts,因此對於tsx就當作樂呵樂呵。空有ts的後綴,其實是js(語法)。總共就一個頁面,頁面地址tsx文件。git
爲了簡潔大方明瞭 咱們這裏直接引用了antd的部分組件github
import { Button,Table,Upload } from 'antd';
<Upload {...uploadProps}>
<Button type="primary" >Excel導入</Button>
</Upload>
<Button type="primary" onClick={this.handleExportAll}>Excel導出數據</Button>
<Button type="primary" onClick={this.handleExportDocument}>Excel導出格式文件</Button>
<Table columns={columns} dataSource={data} bordered></Table>
複製代碼
xlsx
介紹npm install xlsx --save-dev
複製代碼
嘗試解析data數據 解析的類型
複製代碼
是工做簿中的工做表的有序列表
複製代碼
將工做簿對象轉換爲JSON對象數組
複製代碼
更多api可查看 xlsx git 官網npm
/*組件部分*/
<Upload {...uploadProps}>
<Button type="primary" >Excel導入</Button>
</Upload>
複製代碼
/*js部分*/
const uploadProps={
onRemove: file => {
this.setState(state => ({
data:[],
fileList:[]
}));
},
accept: ".xls,.xlsx,application/vnd.ms-excel",
beforeUpload: (file) => {
const _this=this;
const f = file;
const reader = new FileReader();
reader.onload = function (e) {
const datas = e.target.result;
const workbook = XLSX.read(datas, {
type: 'binary'
});//嘗試解析datas
const first_worksheet = workbook.Sheets[workbook.SheetNames[0]];//是工做簿中的工做表的有序列表
const jsonArr = XLSX.utils.sheet_to_json(first_worksheet, { header: 1 });//將工做簿對象轉換爲JSON對象數組
_this.handleImpotedJson(jsonArr, file);
};
reader.readAsBinaryString(f);
return false;
},
fileList,
};
複製代碼
onRemove
是當移除文件時觸發的操做,這裏的操做就是清除數據。accept
是接受上傳的文件類型。beforeUpload
是上傳文件以前的鉤子,參數爲上傳的文件,若返回 false 則中止上傳,此處只是進行數據的轉化,沒有真實上傳。fileList
是文件列表。更多api請看antd upload官網json
總共就那麼幾行api
const f = file;
const reader = new FileReader();
reader.onload = function (e) {
const datas = e.target.result;
const workbook = XLSX.read(datas, {
type: 'binary'
});//嘗試解析datas
const first_worksheet = workbook.Sheets[workbook.SheetNames[0]];//是工做簿中的工做表的有序列表
const jsonArr = XLSX.utils.sheet_to_json(first_worksheet, { header: 1 });//將工做簿對象轉換爲JSON對象數組
_this.handleImpotedJson(jsonArr, file);
};
reader.readAsBinaryString(f);
複製代碼
1 .首先FileReader對象實例化一個file對象數組
2 .在file對象onload事件裏進行處理微信
3 .使用XLSX.read解析dataantd
4 .first_worksheet是解析的數據
5 .XLSX.utils.sheet_to_json(first_worksheet, { header: 1 });將工做簿對象轉化爲JSON對象
6 .handleImpotedJson方法能夠將json對象進行一系列操做 轉化到表格裏
handleImpotedJson = (array, file) => {
const header = array[0];//頭部數據 ["姓名",...]
const entozh = this.formatTitleOrFileld('title', 'dataIndex');//將表字段數組形式轉化爲對象形式,如:{"姓名":"name",...}
const firstRow = header.map(item => entozh[item]);//能夠獲取到行屬性 ["name",...]
const newArray = [...array];
newArray.splice(0, 1);//去除表頭
const json = newArray.map((item, index) => {
const newitem = {};
item.forEach((im, i) => {
const newKey = firstRow[i] || i;
newitem[newKey] = im
})
return newitem;
});//將存在表頭定義字段的值賦值
const formatData = json.map(item => ({
name: item.name,
age: item.age,
address: item.address,
}))//篩選出本身須要的屬性
this.setState({ data: formatData, fileList: [file] });
return formatData;
}
formatTitleOrFileld = (a, b) => {
const entozh = {};
this.state.columns.forEach(item => {
entozh[item[a]] = item[b]
})
return entozh;
}
複製代碼
<Button type="primary" onClick={this.handleExportAll}>Excel導出數據</Button>
handleExportAll = (e) => {
const entozh = {
"name":"姓名",
"age":"年齡",
"address":"地址"
}
const nowdata = this.state.data;
const json = nowdata.map((item) => {
return Object.keys(item).reduce((newData, key) => {
const newKey = entozh[key] || key
newData[newKey] = item[key]
return newData
}, {})
});
const sheet = XLSX.utils.json_to_sheet(json);
this.openDownloadDialog(this.sheet2blob(sheet,undefined), `所有信息.xlsx`);
}
openDownloadDialog = (url, saveName) => {
if (typeof url == 'object' && url instanceof Blob) {
url = URL.createObjectURL(url); // 建立blob地址
}
var aLink = document.createElement('a');
aLink.href = url;
aLink.download = saveName || ''; // HTML5新增的屬性,指定保存文件名,能夠不要後綴,注意,file:///模式下不會生效
var event;
if (window.MouseEvent) event = new MouseEvent('click');
else {
event = document.createEvent('MouseEvents');
event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
}
aLink.dispatchEvent(event);
}
sheet2blob = (sheet, sheetName) => {
sheetName = sheetName || 'sheet1';
var workbook = {
SheetNames: [sheetName],
Sheets: {}
};
workbook.Sheets[sheetName] = sheet; // 生成excel的配置項
var wopts = {
bookType: 'xlsx', // 要生成的文件類型
bookSST: false, // 是否生成Shared String Table,官方解釋是,若是開啓生成速度會降低,但在低版本IOS設備上有更好的兼容性
type: 'binary'
};
var wbout = XLSX.write(workbook, wopts);
var blob = new Blob([s2ab(wbout)], {
type: "application/octet-stream"
}); // 字符串轉ArrayBuffer
function s2ab(s) {
var buf = new ArrayBuffer(s.length);
var view = new Uint8Array(buf);
for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
return buf;
}
return blob;
}
複製代碼
字面意思,能夠將工做簿對象轉化爲json對象
複製代碼
此方法建立了a標籤 利用a標籤的download屬性進行下載文件
複製代碼
能夠將工做簿對象轉化爲咱們須要的
複製代碼
其實和上面同樣 惟獨把表頭數據保存下來就行惟一的區別就是
let nowdata = [
{"name":""},
{"age":""},
{"address":""},
];
複製代碼
將state中的data對象轉化爲空數組形式便可。
有不懂的能夠加我微信詢問我