複数シートで構成されたEXCELから指定シート情報を一覧にインポートする機能
業務アプリでは、EXCEL情報を読み込んだり、EXCEL情報で出力する操作がよく利用されますが、今回の記事は、複数シートで構成されたEXCELから指定したシートの情報を取り出して、一覧に表示する機能です。EXCELに1つのシートのみ定義したEXCELの利用は簡単ですが、複数シート構成のEXCELでは。直前で編集し、保存したシート(保存前にアクティブであったシート)が読みだされてしまう仕様がほとんどです。EXCEL情報を読み込むときに、シート名を指定する実装ができれば、問題は発生しにくくなります。
1つ前の記事(No.32)で電子帳簿にアマゾン領収書を一括格納する事例を紹介していますが、この記事を書いたときには、EXCELのシート名を指定する方法がはっきりわかっていなく、EXCEL側で注意が必要でした。その後、マニュアルやフォーラムを確認し、シート名を指定する方法が判明しましたので、本記事でサンプルを作成し、紹介します。
サンプルでは、ソースコード内でシート名を指定していますが、EXCELをインポート操作するときに、対象EXCELのシート情報を配列で読み出すことも可能です。シート名がダイナミックに変更されるようなEXCELを使用する場合は、その考慮が必要です。
この記事は、事前にシート名が判断できる仕様で実装しています。
1つのEXCELに"list1"と"list2"の2つのシートがあるEXCELを使います。
以下のような情報で作成しています。
Webixで作成した画面は以下のような画面です。
list1を読み込むボタンとlist2を読み込むボタンを実装し、下部に一覧を定義しています。
実際に読み込む操作を実行すると、
list2を読み込むと、以下のようになります。
どちらの動作も、ボタン押下でEXCELファイルを選択するダイアログが表示されるので、EXCELファイルを指定します。
webixのuploader機能を利用して、onBeforeFileAddのイベント内でEXCELファイルを読み込み、一覧に反映後、イベントはreturn false;で終了させれば、upload操作は中断となり、一覧に反映だけできます。
webix.DataDriver.excel.toObjectとwebix.DataDriver.excel.getSheetを使用します。
var sheet = webix.DataDriver.excel.getSheet(data, { name:sheet_name});
const records = sheet.data;
のように、シート名を指定すると、そのシートの情報が変数recordsに、連想配列で格納されます。
ブラウザのデバッガーで確認すると、以下のようになっています。(list1シートの場合)
以下、作成したサンプルソースです。
ZTEST_EXCEL_import_sample.php
<?php
//======================================================================
//File Name : ZTEST_EXCEL_import_sample.php
//Encoding : UTF-8
//Creation Date : 2024-05-27
//
//Copyright © 2024 sunsunfarm. All rights reserved.
//
//This source code or any portion thereof must not be
//reproduced or used in any manner whatsoever.
//======================================================================
$TITLE_INFO ="EXCEL_import_sample";
$VER_INFO ="V01L01";
$JOB_INFO = "ZTEST";
define('ROOT_PATH','/var/www/html/webix01'); //ソースを保存しているパス(動作環境に応じて記述する必要あり)
define('SUB_FOLDER','/webix01'); //サブフォルダを指定したURL
$myfilename = basename(__FILE__); //自分自身のファイル名取得
$userid = '';
$logheader = 'userid='.$userid.', '.$myfilename.':';//ログ出力時のヘッダー情報(自ファイル名,ログインIDを付与)
if(isset($_GET['userid'])){
$userid = $_GET['userid'];
}
else{
error_log($logheader.' userid not found');
header("HTTP/1.0 404 Not Found");
exit;
}
$logheader = 'userid='.$userid.', '.$myfilename.':';
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="/webix_GPL_1020/css/materialdesignicons.min.css" type="text/css" charset="utf-8">
<script src="/webix_GPL_1020/webix.js"></script>
<link href="/webix_GPL_1020/skins/compact.css?<?php echo date('Ymd-H'); ?>" rel="stylesheet" type="text/css">
<link href="<?php echo SUB_FOLDER; ?>/commonlib/webix_custom_css.css?<?php echo date('Ymd-H'); ?>" rel="stylesheet" type="text/css">
<link rel="icon" href="<?php echo SUB_FOLDER; ?>/image/webix_64.ico">
<script src="<?php echo SUB_FOLDER; ?>/commonlib/webix_common_lib.js"></script>
<style>
</style>
<title><?php echo $TITLE_INFO.' '.$JOB_INFO.' ('.$VER_INFO.')' ?></title>
</head>
<body>
<script type="text/javascript" charset="utf-8">
webix.i18n.setLocale("ja-JP");
<?php
include('../../commonlib/CM0080_screen_control.php'); //画面制御共通関数
?>
//ファイル名から拡張子を取得する関数
function ZTTEST_getExt(filename)
{
var pos = filename.lastIndexOf('.');
if (pos === -1) return '';
return filename.slice(pos + 1);
}
var form_collection = [
{ view:"label", height:50, template:"<span style='font-weight:bold; font-size:180%;'>EXCEL_import_sample</span>",width:890},
{ margin:5, cols:[
{ view:"uploader", value:"EXCEL選択(list1)",width: 180,id:"recored_import_btn",
on:{
onBeforeFileAdd: function(upload){
if(ZTTEST_getExt(upload.file.name) != "xlsx"){
webix.alert("指定ファイル『"+upload.file.name+"』はEXCELフォーマットでありません。<br>ファイルを再確認してください。");
}
else{
webix.DataDriver.excel.toObject(upload.file).then(function(data){
try{
const records1 = data.sheets["rename_lists"];
var sheet_name = "list1";
var sheet = webix.DataDriver.excel.getSheet(data, { name:sheet_name});
const records = sheet.data;
var import_records = [];
for(var i=1; i<records.length; i++){
var temp_array = {}; //連想配列にするには{}で初期化する
temp_array["id"]= records[i][0];
temp_array["name"]= records[i][1];
temp_array["address"]= records[i][2];
import_records[i-1] = temp_array;
}
$$("ZTTEST_datatable").clearAll(); //一覧を一度クリア
CM0080_datatable_filter_clear("ZTTEST_datatable");
$$("ZTTEST_datatable").parse(import_records);
var count_info = import_records.length;
$$("select_count").setValue(String(count_info));
$$("sheet_name" ).setValue(sheet_name);
webix.alert("シート:"+sheet_name+"をインポートしました。");
}catch(e){
webix.alert("EXCEL インポート操作で<br>エラーが発生しました。:"+ e.message);
}
});
}
return false;
}
}
},
{ view:"uploader", value:"EXCEL選択(list2)",width: 180,id:"recored_import_btn2",
on:{
onBeforeFileAdd: function(upload){
if(ZTTEST_getExt(upload.file.name) != "xlsx"){
webix.alert("指定ファイル『"+upload.file.name+"』はEXCELフォーマットでありません。<br>ファイルを再確認してください。");
}
else{
webix.DataDriver.excel.toObject(upload.file).then(function(data){
try{
const records1 = data.sheets["rename_lists"];
var sheet_name = "list2";
var sheet = webix.DataDriver.excel.getSheet(data, { name:sheet_name});
const records = sheet.data;
var import_records = [];
for(var i=1; i<records.length; i++){
var temp_array = {}; //連想配列にするには{}で初期化する
temp_array["id"]= records[i][0];
temp_array["name"]= records[i][1];
temp_array["address"]= records[i][2];
import_records[i-1] = temp_array;
}
$$("ZTTEST_datatable").clearAll(); //一覧を一度クリア
CM0080_datatable_filter_clear("ZTTEST_datatable");
$$("ZTTEST_datatable").parse(import_records);
var count_info = import_records.length;
$$("select_count").setValue(String(count_info));
$$("sheet_name" ).setValue(sheet_name);
webix.alert("シート:"+sheet_name+"をインポートしました。");
}catch(e){
webix.alert("EXCEL インポート操作で<br>エラーが発生しました。:"+ e.message);
}
});
}
return false;
}
}
},
]},
];
var ZTTEST_datatable = {
id: "ZTTEST_datatable",
type:"clean",
view:"datatable",
columnWidth:400,
resize:true,
select:"cell",
columns:[
{ id:"id" ,header:"行", css:{"text-align":"right"}, width:50, sort:"int"},
{ id:"name" ,header:["名称", { content:"selectFilter"}],width:140, sort:"string"},
{ id:"address" ,header:["所在地", { content:"selectFilter"}],width:140, sort:"string"},
],
resizeColumn:true,
resizeRow:true,
scroll:"xy",
data:[],
datatype:"json",
};
webix.ui({
padding: 10,
rows:[{
view:"form", //作成されるエレメントの種類
id: "ZTTEST_form", //参照用のID情報
scroll:false, //構成画面のスクロール設定
elements:form_collection , //フォームの構成要素を指定
margin:3,
},
{cols:[
{view:"text", label:"対象(件)", labelWidth:120,name:"select_count",id:"select_count",value:0 ,width:200, inputAlign:"right",labelAlign:"right",readonly:true },
{view:"text", label:"シート" , labelWidth:80 ,name:"sheet_name" ,id:"sheet_name" ,value:"",width:200, labelAlign:"right",readonly:true },
{view:"label",label:"", width:650,name:"comment",id:"comment"},
]},
ZTTEST_datatable,
]
});
</script>
</body>
</html>
複数のシートを持つEXCELを自由にインポート操作できると、応用範囲が広がりますね。ぜひ、活用してみてください。(webixライブラリの詳細は、別の記事などを参照してみてください。)