{"id":20144168,"url":"https://github.com/quansitech/qs-grid-import","last_synced_at":"2025-08-24T06:34:40.292Z","repository":{"id":36905883,"uuid":"230573907","full_name":"quansitech/qs-grid-import","owner":"quansitech","description":"将excel转成web grid的方式导入","archived":false,"fork":false,"pushed_at":"2023-11-09T02:32:51.000Z","size":1462,"stargazers_count":1,"open_issues_count":3,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-19T19:28:37.221Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/quansitech.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-12-28T07:16:22.000Z","updated_at":"2023-12-09T05:07:27.000Z","dependencies_parsed_at":"2025-04-09T18:53:52.245Z","dependency_job_id":"820f54eb-aa83-4db8-9b06-2c7f24432528","html_url":"https://github.com/quansitech/qs-grid-import","commit_stats":null,"previous_names":[],"tags_count":36,"template":false,"template_full_name":null,"purl":"pkg:github/quansitech/qs-grid-import","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quansitech%2Fqs-grid-import","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quansitech%2Fqs-grid-import/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quansitech%2Fqs-grid-import/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quansitech%2Fqs-grid-import/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/quansitech","download_url":"https://codeload.github.com/quansitech/qs-grid-import/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quansitech%2Fqs-grid-import/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271808582,"owners_count":24825527,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-24T02:00:11.135Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-13T22:09:03.574Z","updated_at":"2025-08-24T06:34:40.226Z","avatar_url":"https://github.com/quansitech.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"## 介绍\n\u003e 在实际项目中，经常能遇到用户想用excel导入数据的场景。而通过excel编辑的数据很难控制数据的准确性和规范性。\n\u003e 而Grid-import要求用户先将excel数据导入系统，系统会自动转换出对应的web表格数据，让用户编辑和查看对应的出错提示，提交导入系统。\n\u003e 从而将不可控数据转变成可控的过程。\n\n## 特点\n+ 采用ant组件开发\n+ 理论上支持无限嵌套子母表\n+ 自动完成excel到grid格式的转换，开发者仅需关心业务逻辑接口\n+ [qs-excel](https://github.com/tiderjian/qs-excel)完成excel的操作, gridImport仅关心web表格生成和完成两个组件间不同的数据格式转换\n+ 支持导出excel错误信息，可批量更正后重新导入\n\n## 安装\n```php\ncomposer require tiderjian/qs-grid-import\n\n//找到代码包里的js文件夹\nnpm i //完成前端依赖包的安装\nnpm run build //编译js文件，编译出的文件在dist/grid-import-bundle.js 该文件的使用见下面的教程\n```\n\n## 截图\n将excel数据转换成web grid\n\u003cimg src=\"https://user-images.githubusercontent.com/1665649/71555235-cc3f0600-2a64-11ea-8b6e-8f45adae5750.png\" /\u003e\n\n导入出错错误提示\n\u003cimg src=\"https://user-images.githubusercontent.com/1665649/71555252-263fcb80-2a65-11ea-86d0-f789be74a7fc.png\" /\u003e\n\n错误提示2\n\u003cimg src=\"https://user-images.githubusercontent.com/1665649/71555263-4b343e80-2a65-11ea-8877-1226d8de6fa8.png\" /\u003e\n\n导入成功，确定跳转\n\u003cimg src=\"https://user-images.githubusercontent.com/1665649/71555287-846cae80-2a65-11ea-8015-c9aae20271bf.png\" /\u003e\n## 用法\n\n### 定义表格配置\n+ unique 唯一设置\n\n  设置哪些字段必须是唯一的，否则报错，可以是复合字段设置。\n  \n  设置类型数组，设置值为data 配置对应的key\n\n+ data 配置值\n\n    \u003e1. title 标题\n    \u003e2. key 列关键字\n    \u003e3. [type 列类型](#列类型)\n    \u003e4. [required 是否必填](#是否必填)\n    \u003e5. [validate_callback 验证回调](#验证回调)\n    \u003e6. width 列宽度百分比\n    \u003e7. validate_err_msg  自定义类型验证错误提示\n \n+ 代码示例\n```php\n$options = [\n    'unique' =\u003e [ 'project_id' ], //如果是复合唯一，设置多个key值 ['project_id', 'name']\n    'data' =\u003e [\n        [\n            'title' =\u003e '项目',\n            'key' =\u003e 'project_id',\n            'type' =\u003e CellType::SELECT,\n            'options' =\u003e [ 1 =\u003e '项目1', 2 =\u003e '项目2'],\n            'required' =\u003e true,\n            'width' =\u003e '20%',\n            'validate_callback' =\u003e function($val){\n                //验证逻辑\n            }\n        ],\n        [\n             'title' =\u003e '立项日期',\n             'key' =\u003e 'create_date',\n             'type' =\u003e CellType::DATE,\n             'required' =\u003e true,\n             'validate_err_msg' =\u003e '立项格式不正确，参考: 2020-01-01' //通过该设置重置日期类型的错误提示\n        ],\n        [\n             'title' =\u003e '手机',\n             'key' =\u003e 'telephone',\n             'type' =\u003e CellType::INPUT,\n             'required' =\u003e function($val, $row){\n                return !$row['telephone'] \u0026\u0026 !$row['email'];\n             },\n             'required_err_msg' =\u003e '手机、邮箱不能同时为空' //通过该设置重置必填的错误提示\n        ],\n        [\n             'title' =\u003e '邮箱',\n             'key' =\u003e 'email',\n             'type' =\u003e CellType::INPUT,\n             'required' =\u003e function($val, $row){\n                return !$row['telephone'] \u0026\u0026 !$row['email'];\n             },\n             'required_err_msg' =\u003e '手机、邮箱不能同时为空' //通过该设置重置必填的错误提示\n        ]       \n    ]\n];\n```\n\n+ [children 子母表配置](#子母表)\n\n#### 列类型\n\n1. CellType::INPUT  单行输入框\n\n2. CellType::DATE  日期 （格式: 2021-06-17）\n\n3. CellType::INPUTNUMBER 数字\n\n4. CellType::SELECT 下拉选择\n     \u003e 类型为下拉选择是，配置值必须设置 options 下拉值，格式为键值对的数组\n     \u003e ```php\n     \u003e $project_arr = [\n     \u003e     1 =\u003e '项目1',\n     \u003e     2 =\u003e '项目2',\n     \u003e     3 =\u003e '项目3'\n     \u003e ];\n     \u003e \n     \u003e //省略详细配置，仅演示options的设置，以下雷同，不重复提示\n     \u003e 'options' =\u003e $project_arr\n     \u003e```\n\nPS. 除INPUT类型外，其余类型都在提交时会对提交值分别进行类型有效性验证\n\n5. CellType::MULTI_SELECT  多选\n    \u003e 设置方法同 CellType::SELECT\n    \u003e 唯一的区别是excel是文本输入类型，以半角英文逗号分隔\n    \u003e \n    \u003e 独有设置 ignore\n    \u003e ```php\n    \u003e  'ignore' =\u003e false // 设置为false后，保留不在options里的值，默认为ture\n    \u003e ``` \n\n6. CellType::DATETIME 日期+时间（格式: 2021-06-17 12:30:30）\n\n#### 是否必填\n\n支持2种设置类型\n\n1. 布尔值\n\n    \u003e true表示必填，false表示非必填，默认为false\n\n2. 闭包函数\n    \n    \u003e 可通过该机制动态决定是否为必填项\n    \u003e 1. 第一个参数为该单元格值\n    \u003e 2. 第二个参数为该行的所有值\n    \u003e \n    \u003e ```php\n    \u003e 'required' =\u003e function($val, $row) {\n    \u003e    //业务逻辑 最后 return是否必填的布尔值\n    \u003e }\n    \u003e```\n\n#### 验证回调\n\n\u003e 仅支持闭包函数，接受两个参数, 返回true表示验证通过，返回字符串表示验证不通过，同时表示不通过原因\n\u003e 1. 第一个参数为该单元格值\n\u003e 2. 第二个参数为该行的所有值\n\u003e\n\u003e ```php\n\u003e 'validate_callback' =\u003e function($val, $row){\n\u003e     //业务逻辑\n\u003e }\n\u003e ```\n\n#### 子母表\n\u003e 子母表用于处理多层的数据导入情况，如用户需要在一个excel中，录入不同sheet数据，而不同sheet之间存在数据关联的情形。\n\n\u003e 举例： 一个项目，下面还存在不同的团队需要录入时，此时就可以通过设置二级子母表来一次完成项目和团队的数据导入\n\n\n + children值配置\n \n    \u003e children下的配置值其实与父级的配置一样，唯一不同的是多了个ref_key的值需要配置。该值接收一个数组，每个值表示与父级的关联字段\n    \u003e ```php\n    \u003e $options = [\n    \u003e   'data' =\u003e [\n    \u003e     [\n    \u003e         'title' =\u003e '项目',\n    \u003e         'key' =\u003e 'project_id',\n    \u003e         'type' =\u003e CellType::SELECT,\n    \u003e         'options' =\u003e [ 1 =\u003e '项目1', 2 =\u003e '项目2'],\n    \u003e         'required' =\u003e true,\n    \u003e         'validate_callback' =\u003e function($val){\n    \u003e             //验证逻辑\n    \u003e         }\n    \u003e     ]\n    \u003e   ],\n    \u003e   'children' =\u003e [\n    \u003e      'ref_key' =\u003e [ 'project_id' ],\n    \u003e      'data' =\u003e [\n    \u003e          [\n    \u003e             'title' =\u003e '团队名称',\n    \u003e             'key' =\u003e 'team_name',\n    \u003e             'type' =\u003e CellType::INPUT,\n    \u003e             'required' =\u003e true\n    \u003e          ]\n    \u003e       ] \n    \u003e   ]\n    \u003e ];\n    \u003e```\n                \n PS. 子母表理论上支持无限嵌套，children下还可以继续设置children值，可按实际业务设置更复杂的导入方式。\n \n ### 根据配置值设置导出excel模板\n \n ```php\n//第一个参数为转换驱动\n//第二个参数为上面定义好的$options\n$transcoder = new TranscoderFactory(\"QsExcel\", $options);\n\n//这里的的project和team与上面定义的options子母表关系对应，有多少层嵌套关系就可以转出多少个excel配置值，这里是两层关系\nlist($project, $team) = $transcoder-\u003econvertTo();\n\n//这里是QsExcel的配置格式，可查看上面的qs-excel链接查看说明文档\n$project_options = [\n    'row_count' =\u003e 500,\n    'headers' =\u003e $project\n];\n\n$team_options = [\n    'row_count' =\u003e 500,\n    'headers' =\u003e $team\n];\n\n//创建QsExcel对象，完成模板生成\n$excel = new Excel();\n$excel-\u003eaddBuild((new \\QsExcel\\Builder\\ListBuilder($project_options))-\u003esetSheetName('项目信息'));\n$excel-\u003eaddBuild((new \\QsExcel\\Builder\\ListBuilder($team_options))-\u003esetSheetName('团队信息'));\n$excel-\u003eoutput('项目团队资料导入.xlsx');\n```\n\n### 导入excel表格，生成grid  web表格\n\n```php\n//上传excel文件的路径\n$file_path = '项目团队资料导入.xlsx';\n$excel = new Excel();\n$excel-\u003esetLoadFile($file_path);\n//excel有多少张sheet需要读取数据，就设置多少个Loader\n$excel-\u003eaddLoader(new ListLoader());\n$excel-\u003eaddLoader(new ListLoader());\n$list = $excel-\u003eload();\n\n//这里将表头去掉，否则会出错\n$res = [];\nforeach($list as $v){\n    unset($v[0]);\n    $res[] = $v;\n}\n\n//根据$options生成转换器对象\n$transcoder = new TranscoderFactory(\"QsExcel\", $options);\n//将上传的excel数据导入转换器\n$transcoder-\u003esetData($res);\n//$grid_data为通过转换器后，将excel数据转换成grid的数据格式\n$grid_data = $transcoder-\u003econvertFrom();\n```\n\n下面是前端页面代码\n\n```javascript\n\u003cscript type=\"text/javascript\" src=\"__PUBLIC__/libs-extra/grid-import-bundle.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\nvar opt = {\n    submitUrl: \"\", //设置数据提交到的后端地址\n    successRedirectUrl: \"\", //这里设置导入成功后，点击确定按钮要跳转到的地址\n    data: {json_encode($grid_data)} //将上面生成的grid_data转成json格式赋给data\n};\nimportGrid('id', opt); //第一个参数是需要渲染的dom id， 第二个参数为上面的配置对象\n\u003c/script\u003e\n```\n\n完成这步，就可以看到导入的数据已经转换成web表格，确认没错后可点击提交\n\n### grid数据提交处理\n```php\n//$options不再说明了，就是最开始定义的配置\n$grid_import = new GridImport($options);\n//完成提交数据的填充和验证\n//如果验证有问题，会返回false\n\n$r = $grid_import-\u003efill()-\u003evalidate();\nif($r === false){\n    $errArr = $grid_import-\u003eresponseErrArr();\n    //将$errArr数组转换成json格式返回\n    //前端grid组件接收到后，会在对应的单元格显示出错误提示\n}\n\n//验证通过，通过toArray方法返回导入的数组数据\n$import_datas = $grid_import-\u003etoArray();\n//剩下就是实际的业务逻辑了\n//在处理的过程中如果有进一步出错，可以通过一下代码给grid组件返回出错提示\n//$error_msg为需要显示的错误信息\n$errArr = $grid_import-\u003eresponseErrArr($error_msg);\n//将$errArr数组转换成json格式返回\n//前端grid组件接收到后，会通过警告提示显示出错误原因\n\n//如果数据已经成功插入\n//返回一个200响应即可，grid组件会显示导入成功提示\n```\n\n### 异步导入\n前端组件配置\n```javascript\n\u003cscript type=\"text/javascript\" src=\"__PUBLIC__/libs-extra/grid-import-bundle.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\nvar opt = {\n    async: true,\n    asyncProcessNotify: \"\", //进度请求地址\n    submitUrl: \"\", //设置数据提交到的后端地址\n    successRedirectUrl: \"\", //这里设置导入成功后，点击确定按钮要跳转到的地址\n    data: {:json_encode($grid_data)} //将上面生成的grid_data转成json格式赋给data\n};\nimportGrid('id', opt); //第一个参数是需要渲染的dom id， 第二个参数为上面的配置对象\n\u003c/script\u003e\n```\n\n后端地址配置\n+ submitUrl\n\u003e 验证数据没有问题，启动异步处理逻辑。并返回处理trans_id\n\n+ asyncProcessNotify\n\u003e 1. 接收trans_id , 并根据trans_id查验异步处理进度情况，返回process，通知前端更新进度条\n\u003e 2. 如果处理过程中出错，返回 error: 1, error_msg: 错误原因\n\n\n### 导入中处理异常，返回异常记录\n业务场景：导入数据，如需请求第三方API，当网络异常或者API请求返回错误，需要将异常情况返回给用户\n\n```php\n//上传，excel数据转换等处理可看上面的代码说明，此处仅列出处理数据导入的代码\n$grid_import = new GridImport($options);\n\n$r = $grid_import-\u003efill()-\u003evalidate();\nif($r === false){\n    $errArr = $grid_import-\u003eresponseErrArr();\n    //将$errArr数组转换成json格式返回\n    //前端grid组件接收到后，会在对应的单元格显示出错误提示\n}\nforeach($grid_import-\u003egetGrid()-\u003egetRows() as $index =\u003e \u0026$row){\n    \n    //获取行数据，返回数组格式\n    $row_data = $row-\u003egetRowData();\n    \n    //业务处理代码\n    \n    //处理完成\n    if($r){\n        //可根据业务需要，选择清除处理成功的数据\n        //或者有一条数据不成功都将回滚，可选择不清除\n        $grid_import-\u003egetGrid()-\u003eremoveRow($index);\n    }\n    //处理失败\n    else{\n        //设置具体错误信息\n        $row-\u003esetError('设置错误信息');\n    }\n\n}\n\nif(处理失败){\n    //构造错误应答\n    $errArr = $grid_import-\u003eresponseErrArr();\n    //将$errArr数组转换成json格式返回\n}\n//处理成功\nelse{   \n    //如果数据已经成功插入\n    //返回一个200响应即可，grid组件会显示导入成功提示\n    //如果是异步导入，返回process:100\n}\n```\n\n### 导出excel错误信息\n前端组件配置\n```javascript\n\u003cscript type=\"text/javascript\" src=\"__PUBLIC__/libs-extra/grid-import-bundle.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\nvar opt = {\n    exportErrObj: {\n        filename:\"xxx错误信息.xlsx\",// 导出文件名，默认为 错误信息.xlsx\n        output: true, // 是否支持导出excel错误信息\n    },\n    async: false,\n    asyncProcessNotify: \"\", //进度请求地址\n    submitUrl: \"\", //设置数据提交到的后端地址\n    successRedirectUrl: \"\", //这里设置导入成功后，点击确定按钮要跳转到的地址\n    data: {:json_encode($grid_data)} //将上面生成的grid_data转成json格式赋给data\n};\nimportGrid('id', opt); //第一个参数是需要渲染的dom id， 第二个参数为上面的配置对象\n\u003c/script\u003e\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquansitech%2Fqs-grid-import","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fquansitech%2Fqs-grid-import","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquansitech%2Fqs-grid-import/lists"}