来源:奇兵网络 | 2020-05-29 | 浏览:15091次
几年前采用phpexecl导入过数据,今天又有这个需求,于是开始了踩坑的过程。几年时间变化好大,phpexecl变成了PhpSpreadsheet,再加上yii2框架及各种技术环境的变化,要将各种技术整合起来不易呀。
一、composer安装PhpSpreadsheet
1、composer我是全局安装,直接cmd到当前程序路径,然后:composer require phpoffice/phpspreadsheet
2、我是采用composer阿里云的镜像,才不会被墙:https://developer.aliyun.com/composer
3、PhpSpreadsheet的github地址(composer安装不需要理会这个):https://github.com/PHPOffice/PhpSpreadsheet
三、yii2控制器 : DataController.php
<?php
namespace app\modules\controllers;
use Yii;
use app\modules\models\UploadForm;
use yii\web\UploadedFile;
use app\models\Product;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Reader\Xls;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
/**
*
*/
class DataController extends CommonController
{
public function actionIndexinput()
{
$model = new UploadForm;
$this->layout = "layout1";
return $this->render("inputdata", ['model'=>$model]);
}
public function actionIndexclear()
{
$this->layout = "layout1";
return $this->render("cleardata");
}
public function actionInputdata()
{
$this->layout = "layout1";
$model = new UploadForm();
$prmodel = new Product;
if (Yii::$app->request->isPost) {
$model->file = UploadedFile::getInstance($model, 'file');
if ($model->file && $model->validate()) {
$filename = date('Y-m-d',time()).'_'.rand(1,9999) . '.' . $model->file->extension;
$model->file->saveAs('uploads/' . $filename);
$filepath = 'uploads/' . $filename;
}
}
$Data = $this->importExecl($filepath,0,10, $prmodel);
$num = count($Data);
if($num>1000){
Yii::$app->session->setFlash('info', '一次只能导入1000条以内的数据!');
return $this->render("inputdata", ['model'=>$model]);
}
for ($row = 1; $row <= $num; $row++) {
Yii::$app->db->createCommand()->batchInsert('xy_product', ['name', 'company', 'sex', 'pcnum', 'ticketnum', 'mannum', 'groupnum', 'contact', 'testtime', 'productname'], [$Data[$row]])->execute();
}
Yii::$app->session->setFlash('info', '数据导入成功!');
return $this->render("inputdata", ['model'=>$model]);
}
public function actionCleardata()
{
$this->layout = "layout1";
Product::deleteAll();
Yii::$app->session->setFlash('info', '数据清空成功!');
return $this->render("cleardata");
}
/**
* 使用PHPEXECL导入
*
* @param string $file 文件地址
* @param int $sheet 工作表sheet(传0则获取个sheet)
* @param int $columnCnt 列数(传0则自动获取更大列)
* @param array $options 操作选项
* array mergeCells 合并单元格数组
* array formula 公式数组
* array format 单元格格式数组
*
* @return array
* @throws Exception
*/
function importExecl($file = '', $sheet = 0, $columnCnt = 0, $model)
{
try {
/* 转码 */
$file = iconv("utf-8", "gb2312", $file);
if (empty($file) OR !file_exists($file)) {
throw new \Exception('文件不存在!');
}
/** @var Xlsx $objRead */
$objRead = IOFactory::createReader('Xlsx');
//die("ok");
if (!$objRead->canRead($file)) {
/** @var Xls $objRead */
$objRead = IOFactory::createReader('Xls');
if (!$objRead->canRead($file)) {
throw new \Exception('只支持导入Excel文件!');
}
}
/* 如果不需要获取特殊操作,则只读内容,可以大幅度提升读取Excel效率 */
$objRead->setReadDataOnly(true);
/* 建立excel对象 */
$obj = $objRead->load($file);
/* 获取指定的sheet表 */
$currSheet = $obj->getSheet($sheet);
if (0 == $columnCnt) {
/* 取得更大的列号 */
$columnH = $currSheet->getHighestColumn();
/* 兼容原逻辑,循环时使用的是小于等于 */
$columnCnt = Coordinate::columnIndexFromString($columnH);
}
/* 获取总行数 */
$rowCnt = $currSheet->getHighestRow();
$data = [];
/* 读取内容 */
for ($_row = 1; $_row <= $rowCnt; $_row++) {
$isNull = true;
for ($_column = 1; $_column <= $columnCnt; $_column++) {
$cellName = Coordinate::stringFromColumnIndex($_column);
$cellId = $cellName . $_row;
$cell = $currSheet->getCell($cellId);
if (isset($format) && 'm/d/yyyy' == $format) {
/* 日期格式翻转处理 */
$cell->getStyle()->getNumberFormat()->setFormatCode('yyyy/mm/dd');
}
$data[$_row][$cellName] = trim($currSheet->getCell($cellId)->getFormattedValue()); //$data[$_row][$cellName] 值
if (!empty($data[$_row][$cellName])) {
$isNull = false;
}
}
//return $data; //这里将返回一整行数据
/* 判断是否整行数据为空,是的话删除该行数据 */
if ($isNull) {
unset($data[$_row]);
}
}
return $data;
} catch (\Exception $e) {
throw $e;
}
}
}
?>
四、yii2模型model : UploadForm.php
<?php
namespace app\modules\models;
use yii\base\Model;
class UploadForm extends Model
{
public $file;
public function rules()
{
return [
[['file'], 'file'],
];
}
public function attributeLabels(){
return [
'file'=>'文件上传'
];
}
}
五、yii2视图: inputdata.php
: 注意事项:1、execl表的的数据顺序必须为:姓名 企业名称 性别 机位号 准考证号 身份证号 分组号 联系方式 考试时间 考试类型2、一次只能导入1000条以内的数据
六、其它注意事项
1、PHP低版本及高版本都不行,这是啥坑。7.1.9测试成功。2020.5.28日composer安装PhpSpreadsheet,没有选择安装版本,可能是最新的版本。
2、yii2 数据库操作的两种模式{{%product}}:https://blog.csdn.net/nw_ningwang/article/details/77102610
3、修改数据库字段排序:
https://www.cnblogs.com/yangxiaochu/p/8108976.html
4、参考网址:https://blog.csdn.net/DestinyLordC/article/details/84071456
技术交流:309800818