Yii2:将 excel 列与主记录匹配
Yii2: Match excel column with master record
我正在研究 yii2
。我的数据库中有一个名为 sims
的主 table,所有记录都在其中保存和更新。在我的 GUI 中,这些记录保存在 SIM List
中。现在,有一个用例,我正在向一个人发布模拟人生。发行有两种方式
- 使用创建表单
- 通过excel 文件
两种情况都运行完美。现在,通过 excel 文件发布模拟人生,我想检查 imsi
号码是否在主记录中可用。
波纹管是我的 Import
控制器
public function actionImport(){
$file_name = $_POST['file_name'];
$header_index = $_POST['header_index'];
$fieldSet = $_POST['field'];
$data = \moonland\phpexcel\Excel::widget([
'mode' => 'import',
'fileName' => 'uploads/' . $file_name,
'setFirstRecordAsKeys' => false, // if you want to set the keys of record column with first record, if it not set, the header with use the alphabet column on excel.
'setIndexSheetByName' => false, // set this if your excel data with multiple worksheet, the index of array will be set with the sheet name. If this not set, the index will use numeric.
'getOnlySheet' => 0, // you can set this property if you want to get the specified sheet from the excel data with multiple worksheet.
]);
//loop therogh first sheet
$ok_count = 0;
$status_arr = [];
$final_data = isset($data[0]) ? $data[0] : $data;
foreach($final_data as $key=>$value)
{
if($key <= $header_index) continue;
$sims = new SimIssueanceTransaction();
foreach($value as $k=>$v){
$v = preg_replace('/\s+/', ' ', trim($v));
if(isset($fieldSet[0]['imsi']) && $fieldSet[0]['imsi']==$k){
$sims->sim_id = Sims::imsiToidexcel($v);
$sims->imsi =$v."";
}
if(isset($fieldSet[0]['issued_to']) && $fieldSet[0]['issued_to']==$k){
$sims->issued_to = $v;
}
if (isset($fieldSet[0]['purpose']) && $fieldSet[0]['purpose'] == $k) {
$sims->purpose = $v;
}
}
$sims->issued_at = date('Y-m-d H:i:s');
$sims->issued_by = Yii::$app->user->id;
$sims->historic =1;
if($sims->purpose=='Local SIM Issue')
{
$sims->status = Sims::$status_titles[1];
Sims::change_status($sims->sim_id,Sims::$status_titles[1]);
}
else
{
$sims->status = Sims::$status_titles[2];
Sims::change_status($sims->sim_id,Sims::$status_titles[2]);
}
if($sims->save())
{
$ok_count++;
}
else
{
$status_arr[] = $sims->errors;
}
}
return $this->render('excel_finish', ['records_saved' => $ok_count,'status_arr'=>$status_arr]);
}
我想在下面的条件下添加一个检查
if(isset($fieldSet[0]['imsi']) && $fieldSet[0]['imsi']==$k){
$sims->sim_id = Sims::imsiToidexcel($v);
$sims->imsi =$v."";
}
更新 1
我的Sims
型号低于
public function rules()
{
return [
[['imsi','operator_name','data_details','sms_details','status'], 'required'],
[['created_by', 'updated_by', 'sim_stauts', 'issued_to', 'returned_by', 'historic'], 'integer'],
[['created_at', 'updated_at','returned_at'], 'safe'],
[['imsi', 'operator_name', 'data_details', 'sms_details','bill_date'], 'string', 'max' => 20],
[['sim_number', 'status','credit_limit','plan_name'], 'string', 'max' => 50],
[['monthly_bill'], 'string', 'max' => 100],
//[['imsi'], 'unique'],
[['created_by'], 'exist', 'skipOnError' => true, 'targetClass' => User::className(), 'targetAttribute' => ['created_by' => 'id']],
];
}
public function attributeLabels()
{
return [
'id' => 'ID',
'imsi' => 'Imsi',
'sim_number' => 'Sim Number',
'operator_name' => 'Operator Name',
'data_details' => 'Data Details',
'sms_details' => 'Sms Details',
'monthly_bill' => 'Monthly Bill',
'created_by' => 'Created By',
'created_at' => 'Created At',
'updated_at' => 'Updated At',
'status' => 'Status',
'updated_by' => 'Updated By',
'sim_stauts' => 'Sim Stauts',
'issued_to' => 'Issued To',
'returned_by' => 'Returned By',
'historic' => 'Version',
'returned_at'=>'Returned At',
'bill_date' => 'Billing Date',
'credit_limit' => 'Credit Limit',
'plan_name'=> 'Plan Name'
];
}
更新 2
根据建议我创建了一个函数
protected function findImsi($imsi){
if(($model=Sims::findOne(['imsi'=>$imsi]))!== null){
return true;
}
else{
return false;
}
}
然后在我的 import
控制器中
foreach($final_data as $key=>$value)
{
if($key <= $header_index) continue;
$sims = new SimIssueanceTransaction();
foreach($value as $k=>$v){
$v = preg_replace('/\s+/', ' ', trim($v));
$imsiValid = isset($fieldSet[0]['imsi']) && $fieldSet[0]['imsi'] == $k && $this->findImsi($v);
if ($imsiValid) {
$sims->sim_id = Sims::imsiToidexcel($v);
$sims->imsi = $v . "";
}
else
{
\Yii::$app->getSession()->setFlash('error', '
<div class="alert alert-error alert-dismissable">
<button aria-hidden="true" data-dismiss="alert" class="close" type="button">×</button>
<strong>Error!!! No Record is inserted..</strong> IMSI must be wrong </div>');
return $this->redirect(['simissueancetransaction/excel']);
}
.
.
.
}
.
.
.
}
在上传包含正确值的 excel 文件时,$imsiValid
是 true
但它仍然没有进入 if
条件
通过 var_dump($final_data);
我得到了以下结果
array(3) { [1]=> array(4) { ["A"]=> string(4) "imsi" ["B"]=> string(9) "issued to" ["C"]=> string(7) "purpose" ["D"]=> NULL } [2]=> array(4) { ["A"]=> string(18) "899204031015192575" ["B"]=> float(134) ["C"]=> string(20) "Production SIM Issue" ["D"]=> NULL } [3]=> array(4) { ["A"]=> string(18) "899204031015192576" ["B"]=> float(134) ["C"]=> string(20) "Production SIM Issue"} }
更新 3
下面是另外两个用于上传 excel 文件的动作控制器函数。
public function actionExcel(){
$file_name = "excel_" . Yii::$app->user->id . ".xlsx";
$error = "";
if(isset($_FILES['file'])) {
$path_parts = pathinfo($_FILES["file"]["name"]);
$extension = $path_parts['extension'];
if(!in_array($extension,['xlsx','xls'])){
$error = "Invalid file";
}else {
if (move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/' . $file_name)) {
$this->redirect(Url::to('process?file_name=' . $file_name . "&header_no=" . $_POST['header_no']));
}
}
}
return $this->render("excel",['error'=>$error]);
}
public function actionProcess(){
$file_name = $_GET['file_name'];
// $data = \moonland\phpexcel\Excel::import("uploads/test.xlsx"); // $config is an optional
try {
$header_index = $_GET['header_no'];
$data = \moonland\phpexcel\Excel::widget([
'mode' => 'import',
'fileName' => 'uploads/' . $file_name,
'setFirstRecordAsKeys' => false, // if you want to set the keys of record column with first record, if it not set, the header with use the alphabet column on excel.
'setIndexSheetByName' => false, // set this if your excel data with multiple worksheet, the index of array will be set with the sheet name. If this not set, the index will use numeric.
'getOnlySheet' => 0, // you can set this property if you want to get the specified sheet from the excel data with multiple worksheet.
]);
if (isset($data[0])) {
$headers = $data[0][$header_index];
} else {
$headers = $data[$header_index];
}
}catch (Exception $x){
die("Error");
}
return $this->render('excel_options',['headers'=>$headers,'file_name'=>$file_name,'header_index'=>$header_index]);
}
在这两个函数之后调用 import
函数
保存和更新所有记录的模型是Sims
。
如何将 IMSI 号码与主记录匹配?
非常感谢任何帮助。
我从你的问题中了解到,你有 Sims
模型,其中保存了所有模拟人生以及 imsi
并且在将任何记录插入 [=15= 之前] 你想验证它是否存在于 Sims
中。
如果这是正确的,请执行以下步骤
向您的控制器添加一个方法
protected function findModel($imsi){
if(($model=Sims::findOne(['imsi'=>$imsi])) !== null){
return true;
}
return false;
}
然后替换这些行
$v = preg_replace('/\s+/', ' ', trim($v));
if (isset($fieldSet[0]['imsi']) && $fieldSet[0]['imsi'] == $k) {
$sims->sim_id = Sims::imsiToidexcel($v);
$sims->imsi = $v . "";
}
与以下
$v = preg_replace('/\s+/', ' ', trim($v));
$imsiValid = isset($fieldSet[0]['imsi']) && $fieldSet[0]['imsi'] == $k;
if ($imsiValid) {
if($this->findModel($v)){
$sims->sim_id = Sims::imsiToidexcel($v);
$sims->imsi = $v . "";
}
}
Note :I assume that $v
will have the imsi
when
$fieldSet[0]['imsi']==$k
as you are setting $sims->imsi = $v
inside the condition, other wise change $this->findModel($v)
accordingly
我正在研究 yii2
。我的数据库中有一个名为 sims
的主 table,所有记录都在其中保存和更新。在我的 GUI 中,这些记录保存在 SIM List
中。现在,有一个用例,我正在向一个人发布模拟人生。发行有两种方式
- 使用创建表单
- 通过excel 文件
两种情况都运行完美。现在,通过 excel 文件发布模拟人生,我想检查 imsi
号码是否在主记录中可用。
波纹管是我的 Import
控制器
public function actionImport(){
$file_name = $_POST['file_name'];
$header_index = $_POST['header_index'];
$fieldSet = $_POST['field'];
$data = \moonland\phpexcel\Excel::widget([
'mode' => 'import',
'fileName' => 'uploads/' . $file_name,
'setFirstRecordAsKeys' => false, // if you want to set the keys of record column with first record, if it not set, the header with use the alphabet column on excel.
'setIndexSheetByName' => false, // set this if your excel data with multiple worksheet, the index of array will be set with the sheet name. If this not set, the index will use numeric.
'getOnlySheet' => 0, // you can set this property if you want to get the specified sheet from the excel data with multiple worksheet.
]);
//loop therogh first sheet
$ok_count = 0;
$status_arr = [];
$final_data = isset($data[0]) ? $data[0] : $data;
foreach($final_data as $key=>$value)
{
if($key <= $header_index) continue;
$sims = new SimIssueanceTransaction();
foreach($value as $k=>$v){
$v = preg_replace('/\s+/', ' ', trim($v));
if(isset($fieldSet[0]['imsi']) && $fieldSet[0]['imsi']==$k){
$sims->sim_id = Sims::imsiToidexcel($v);
$sims->imsi =$v."";
}
if(isset($fieldSet[0]['issued_to']) && $fieldSet[0]['issued_to']==$k){
$sims->issued_to = $v;
}
if (isset($fieldSet[0]['purpose']) && $fieldSet[0]['purpose'] == $k) {
$sims->purpose = $v;
}
}
$sims->issued_at = date('Y-m-d H:i:s');
$sims->issued_by = Yii::$app->user->id;
$sims->historic =1;
if($sims->purpose=='Local SIM Issue')
{
$sims->status = Sims::$status_titles[1];
Sims::change_status($sims->sim_id,Sims::$status_titles[1]);
}
else
{
$sims->status = Sims::$status_titles[2];
Sims::change_status($sims->sim_id,Sims::$status_titles[2]);
}
if($sims->save())
{
$ok_count++;
}
else
{
$status_arr[] = $sims->errors;
}
}
return $this->render('excel_finish', ['records_saved' => $ok_count,'status_arr'=>$status_arr]);
}
我想在下面的条件下添加一个检查
if(isset($fieldSet[0]['imsi']) && $fieldSet[0]['imsi']==$k){
$sims->sim_id = Sims::imsiToidexcel($v);
$sims->imsi =$v."";
}
更新 1
我的Sims
型号低于
public function rules()
{
return [
[['imsi','operator_name','data_details','sms_details','status'], 'required'],
[['created_by', 'updated_by', 'sim_stauts', 'issued_to', 'returned_by', 'historic'], 'integer'],
[['created_at', 'updated_at','returned_at'], 'safe'],
[['imsi', 'operator_name', 'data_details', 'sms_details','bill_date'], 'string', 'max' => 20],
[['sim_number', 'status','credit_limit','plan_name'], 'string', 'max' => 50],
[['monthly_bill'], 'string', 'max' => 100],
//[['imsi'], 'unique'],
[['created_by'], 'exist', 'skipOnError' => true, 'targetClass' => User::className(), 'targetAttribute' => ['created_by' => 'id']],
];
}
public function attributeLabels()
{
return [
'id' => 'ID',
'imsi' => 'Imsi',
'sim_number' => 'Sim Number',
'operator_name' => 'Operator Name',
'data_details' => 'Data Details',
'sms_details' => 'Sms Details',
'monthly_bill' => 'Monthly Bill',
'created_by' => 'Created By',
'created_at' => 'Created At',
'updated_at' => 'Updated At',
'status' => 'Status',
'updated_by' => 'Updated By',
'sim_stauts' => 'Sim Stauts',
'issued_to' => 'Issued To',
'returned_by' => 'Returned By',
'historic' => 'Version',
'returned_at'=>'Returned At',
'bill_date' => 'Billing Date',
'credit_limit' => 'Credit Limit',
'plan_name'=> 'Plan Name'
];
}
更新 2
根据建议我创建了一个函数
protected function findImsi($imsi){
if(($model=Sims::findOne(['imsi'=>$imsi]))!== null){
return true;
}
else{
return false;
}
}
然后在我的 import
控制器中
foreach($final_data as $key=>$value)
{
if($key <= $header_index) continue;
$sims = new SimIssueanceTransaction();
foreach($value as $k=>$v){
$v = preg_replace('/\s+/', ' ', trim($v));
$imsiValid = isset($fieldSet[0]['imsi']) && $fieldSet[0]['imsi'] == $k && $this->findImsi($v);
if ($imsiValid) {
$sims->sim_id = Sims::imsiToidexcel($v);
$sims->imsi = $v . "";
}
else
{
\Yii::$app->getSession()->setFlash('error', '
<div class="alert alert-error alert-dismissable">
<button aria-hidden="true" data-dismiss="alert" class="close" type="button">×</button>
<strong>Error!!! No Record is inserted..</strong> IMSI must be wrong </div>');
return $this->redirect(['simissueancetransaction/excel']);
}
.
.
.
}
.
.
.
}
在上传包含正确值的 excel 文件时,$imsiValid
是 true
但它仍然没有进入 if
条件
通过 var_dump($final_data);
我得到了以下结果
array(3) { [1]=> array(4) { ["A"]=> string(4) "imsi" ["B"]=> string(9) "issued to" ["C"]=> string(7) "purpose" ["D"]=> NULL } [2]=> array(4) { ["A"]=> string(18) "899204031015192575" ["B"]=> float(134) ["C"]=> string(20) "Production SIM Issue" ["D"]=> NULL } [3]=> array(4) { ["A"]=> string(18) "899204031015192576" ["B"]=> float(134) ["C"]=> string(20) "Production SIM Issue"} }
更新 3
下面是另外两个用于上传 excel 文件的动作控制器函数。
public function actionExcel(){
$file_name = "excel_" . Yii::$app->user->id . ".xlsx";
$error = "";
if(isset($_FILES['file'])) {
$path_parts = pathinfo($_FILES["file"]["name"]);
$extension = $path_parts['extension'];
if(!in_array($extension,['xlsx','xls'])){
$error = "Invalid file";
}else {
if (move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/' . $file_name)) {
$this->redirect(Url::to('process?file_name=' . $file_name . "&header_no=" . $_POST['header_no']));
}
}
}
return $this->render("excel",['error'=>$error]);
}
public function actionProcess(){
$file_name = $_GET['file_name'];
// $data = \moonland\phpexcel\Excel::import("uploads/test.xlsx"); // $config is an optional
try {
$header_index = $_GET['header_no'];
$data = \moonland\phpexcel\Excel::widget([
'mode' => 'import',
'fileName' => 'uploads/' . $file_name,
'setFirstRecordAsKeys' => false, // if you want to set the keys of record column with first record, if it not set, the header with use the alphabet column on excel.
'setIndexSheetByName' => false, // set this if your excel data with multiple worksheet, the index of array will be set with the sheet name. If this not set, the index will use numeric.
'getOnlySheet' => 0, // you can set this property if you want to get the specified sheet from the excel data with multiple worksheet.
]);
if (isset($data[0])) {
$headers = $data[0][$header_index];
} else {
$headers = $data[$header_index];
}
}catch (Exception $x){
die("Error");
}
return $this->render('excel_options',['headers'=>$headers,'file_name'=>$file_name,'header_index'=>$header_index]);
}
在这两个函数之后调用 import
函数
保存和更新所有记录的模型是Sims
。
如何将 IMSI 号码与主记录匹配?
非常感谢任何帮助。
我从你的问题中了解到,你有 Sims
模型,其中保存了所有模拟人生以及 imsi
并且在将任何记录插入 [=15= 之前] 你想验证它是否存在于 Sims
中。
如果这是正确的,请执行以下步骤
向您的控制器添加一个方法
protected function findModel($imsi){
if(($model=Sims::findOne(['imsi'=>$imsi])) !== null){
return true;
}
return false;
}
然后替换这些行
$v = preg_replace('/\s+/', ' ', trim($v));
if (isset($fieldSet[0]['imsi']) && $fieldSet[0]['imsi'] == $k) {
$sims->sim_id = Sims::imsiToidexcel($v);
$sims->imsi = $v . "";
}
与以下
$v = preg_replace('/\s+/', ' ', trim($v));
$imsiValid = isset($fieldSet[0]['imsi']) && $fieldSet[0]['imsi'] == $k;
if ($imsiValid) {
if($this->findModel($v)){
$sims->sim_id = Sims::imsiToidexcel($v);
$sims->imsi = $v . "";
}
}
Note :I assume that
$v
will have theimsi
when$fieldSet[0]['imsi']==$k
as you are setting$sims->imsi = $v
inside the condition, other wise change$this->findModel($v)
accordingly