blog

js-xlsxフロントエンドがエクセルデータを読み込む

効果は以下のようになります # ファイルのアップロード # ExcelDataの読み込み; エクセルテーブルのヘッダーを取得し、基本テンプレートにマッチするかどうかを判断する 自己調整マッチングヘッダ...

Aug 22, 2020 · 4 min. read
シェア

レンダリングは以下の通り。

オプション・パラメータの読み込みとオプション・パラメータの書式設定に注意

workbook = XLSX.read(result, { type: "array",cellDates:true, cellNF: false, cellText:false});
XLSX.utils.sheet_to_json(workbook.Sheets[sheet],{raw:false, dateNF:"yyyy-mm-DD"})

#ファイルアップロード

uploadChange = async info => {
console.log(info);
fileList= info.fileList
file=info.file
this.readExcel(file)
 

# ExcelDataを読み込みます。

readExcel = file => {
 console.log('readExcel')
 const fileReader = new FileReader();
 fileReader.onload = event => {
 try {
 const { result } = event.target;
 // バイナリストリーム読み込みとしてエクセルテーブルオブジェクト全体を取得する。
 //const workbook = XLSX.read(result, { type: "binary" });
 const workbook = XLSX.read(result, { type: "array",cellDates:true, cellNF: false, cellText:false});
 let data = []; // 取得したデータを格納する
 let sheetHeader = [];
 // 各ワークシートを繰り返し読み込む
 for (const sheet in workbook.Sheets) {
 if (workbook.Sheets.hasOwnProperty(sheet)) {
 // シートを使う_to_json エクセルをjsonデータに変換する方法
 data = data.concat(
 XLSX.utils.sheet_to_json(workbook.Sheets[sheet],{raw:false, dateNF:"yyyy-mm-DD"})
 );
 //テーブルの最初の行のデータ・リターンの配列を取得する;
 sheetHeader = this.getExcelTitleRow(workbook.Sheets[sheet]);
 break; // 最初の表だけが取られている場合、その行のコメントを外す
 }
 }
 this.metaAction.sfs({
 "data.excelData": fromJS(data),
 "data.sheetHeader": fromJS(sheetHeader)
 });
 console.log("dd",data, sheetHeader);
 } catch (e) {
 console.log("Excel解析の失敗");
 return;
 }
 fileReader.readAsArrayBuffer(file);//ie11と互換性がある
 /* if(fileReader.readAsBinaryString){
 // ファイルをバイナリとして開く
 fileReader.readAsBinaryString(file);//ie11 
 }else{
 fileReader.readAsArrayBuffer(file);
 } */
};

エクセルの表ヘッダーの取得

getExcelTitleRow = sheet => {
 if(sheet == null || sheet["!ref"] == null) return [];
 let val, hdr = [] ,v=0, vv="",cols=[];
 let range=XLSX.utils.decode_range(sheet["!ref"])
 let c = range.e.c;
 let CC = 0;
 let rr = XLSX.utils.encode_row(range.s.r)
 for (let i = 0; i <= c; i++) {
 cols[i] = XLSX.utils.encode_col(i);
 let val =sheet[cols[i] + rr];
 vv = v = XLSX.utils.format_cell(val, null);
 if(v == null||v =='') continue;
 let counter=0
 for(CC = 0; CC < hdr.length; ++CC){
 if(hdr[CC] == vv) vv = v + "_" + (++counter);
 }
 hdr.push(vv);
 }
 return hdr;
};·

基本テンプレートが満たされているかどうかの判断

 sheetDataAutoMatch = (baseTemplate, sheetHeader) => {
 let isBaseTemplate = true; //基本テンプレートと完全に一致するかどうか
 let relationShip = []; //テンプレート・マッチングの関係
 baseTemplate.forEach(item => {
 if (sheetHeader.includes(item.baseTitle)) {
 relationShip.push({ ...item, excelTitle: item.baseTitle });
 }else if(sheetHeader.includes("*"+item.baseTitle)){
 relationShip.push({ ...item, excelTitle: "*"+item.baseTitle });
 } else {
 isBaseTemplate = false;
 let synonym = item.synonym ? [...item.synonym] : [];
 let isMatchsynonym = false;
 synonym.forEach(synonymItem => {
 if (sheetHeader.includes(synonymItem)) {
 relationShip.push({
 ...item,
 excelTitle: synonymItem
 });
 isMatchsynonym = true;
 }else if(sheetHeader.includes("*"+synonymItem)){
 relationShip.push({
 ...item,
 excelTitle: "*"+synonymItem
 });
 isMatchsynonym = true;
 }
 });
 isMatchsynonym
 ? ""
 : relationShip.push({
 ...item,
 excelTitle: ""
 });
 }
 });
 return { isBaseTemplate, relationShip };
 };

自己調整マッチングヘッダ

 let baseTemplate = []; //基本テンプレート
 let excelData = []; //EXCEL 
 let relationShip = []; //EXCELマッチング関係
 let sheetHeader = []; //EXCELデータからテーブルヘッダを抽出する
 let dropDownSheetHeader = []; //調整可能なエクセルテーブルヘッダー
//Excelテーブルヘッダのマッチングを修正する
sheetHeaderChange = (e, fieldName) => {
 let relationShip = this.metaAction.gf("data.relationShip").toJS();
 let sheetHeader = this.metaAction.gf("data.sheetHeader").toJS();
 relationShip = relationShip.map(item => {
 if (item.fieldName == fieldName) {
 item.excelTitle = e.key == "0" ? "" : e.key;
 }
 return item;
 });
 let dropDownSheetHeader = this.getDropDownSheetHeader(
 relationShip,
 sheetHeader
 );
 this.metaAction.sfs({
 "data.relationShip": fromJS(relationShip),
 "data.dropDownSheetHeader": fromJS(dropDownSheetHeader)
 });
};
Read next

Reactフックの例 --- useMemo

useMemo と useMemo は、他の無関係なパラメータの変更によってコンポーネントが再レンダリングされるのを防ぐという点で似ています。 クラスコンポーネントの場合、useMemoはFunctionコンポーネントに適用されます。また、パラメータを指定することもできます。

Aug 22, 2020 · 1 min read