Yii2:将 excel 列与主记录匹配

Yii2: Match excel column with master record

我正在研究 yii2。我的数据库中有一个名为 sims 的主 table,所有记录都在其中保存和更新。在我的 GUI 中,这些记录保存在 SIM List 中。现在,有一个用例,我正在向一个人发布模拟人生。发行有两种方式

  1. 使用创建表单
  2. 通过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 文件时,$imsiValidtrue 但它仍然没有进入 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