来源:https://blog.csdn.net/qq_34625397/article/details/136225972
前提是已经安装了phpspreadsheet ( composer require phpoffice/phpspreadsheet )
一、 数据拼装,调用excel类
```
<?php
/**
* 电子台账
* Date: 2023/4/20
* Time: 17:28
*/
namespace app\store\controller;
use app\common\controller\Excel;
use app\common\model\ModelRedis;
use app\store\model\ModelSaleStoreInput;
class Ledger extends \app\ApiCommon
{
/**
* 导出数据拼装
* @param $ids string 出库id 列表 1,2,3,4
*/
public function export_input($ids,$start,$end){
$where = [];
if(!empty($start) && !empty($end)){
$where[] = ['ctime','>=',strtotime($start)];
$where[] = ['ctime','<=',strtotime($end)];
}else{
$where[] = ['id','in',$ids];
}
$list = ModelSaleStoreInput::where($where)->field($field)->select()->toArray();
if(empty($list)){
return $this->apiError('数据不存在');
}
$data = $list;
//此处说明:解决数字太长尾数变000的问题
//由于数字超过15位,会被显示成0或者加小数点处理。造成这种情况是由于Excel内置的数值有效范围是15位。超过15位,如果要显示的话,就需要转换成非数字格式。比如文本格式。
foreach ($data as $key => $value) {
$tmp = [];
$explode_no = self::decode_explode_no($value['explode_no']);
array_push($tmp,"\t".$value['id']."\t");
array_push($tmp,"\t".$value['ctime']."\t");
array_push($tmp,"\t".$value['store_name']."\t");
array_push($tmp,"\t".$value['name']."\t");
array_push($tmp,"\t".$value['spec_name']."\t");
array_push($tmp,"\t".$value['amount']."\t");
array_push($tmp,"\t".$explode_no."\t");
array_push($tmp,"\t".$value['supply_company']."\t");
array_push($tmp,"\t".$value['deliver']."\t");
array_push($tmp,"\t".self::desensitizedIdCard($value['deliver_idcard'])."\t");
array_push($tmp,"\t".$value['carry_no']."\t");
array_push($tmp,"\t".$value['buy_no']."\t");
array_push($tmp,"\t".$value['storeman_names']."\t");
array_push($tmp,"\t".$value['storeman_signs']."\t");
array_push($tmp,"\t".$value['safety_name']."\t");
array_push($tmp,"\t".$value['safety_sign']."\t");
$data[$key] = $tmp;
}
//保存到本地临时目录
$path = './uploads/tmp/';
$excel_name = '数据盘点';
$title = ['id','时间','仓库名','物品名称','品种规格','物品数量','编号','供货单位','送货人','身份证号','运输证号','购买证号','库管员','库管员签字','安全员','安全员签字'];
$file_name = date('Y-m-d').rand(1000,9999).$excel_name.'.xlsx';
$res = Excel::export($title,$data,$path,$file_name);
return $res;
}
}
```
二、封装好的Excel类:注意远程图片必须base64后缓存到本地再写入excel。
```
<?php
/**
* excel导入导出公共类
* Date: 2023/4/27
* Time: 18:39
*/
namespace app\common\controller;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
use think\exception\ValidateException;
use think\facade\Filesystem;
class Excel
{
/**
* 数据导出Excel
* @param array $title 表头
* @param array $data 数据源
* @param string $path 目录
* @param string $file_name 文件名称
* @return array
*/
public static function export($title = [], $data = [],$path,$file_name="")
{
try{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
// 表头单元格内容 第一行
$titCol = 'A';
foreach ($title as $value) {
// 单元格内容写入
$sheet->setCellValue($titCol . '1', $value);
$titCol++;
}
//单元格内容居中
$sheet->getDefaultRowDimension()->setRowHeight(60);//默认行高60
$sheet->getDefaultColumnDimension()->setAutoSize(true);//列宽自适应
$sheet->getStyle('A:'.$titCol)->getAlignment()->setVertical('center');//内容容垂居中
$sheet->getStyle('A:'.$titCol)->getAlignment()->setHorizontal('center');//内水平直居中
// 从第二行开始写入数据
$row = 2;
foreach ($data as $item) {
$dataCol = 'A';
foreach ($item as $value) {
// 单元格内容写入
$values = explode(".",$value);
$ext = trim(end($values));
if(in_array($ext,['jpg','png','jpeg'])){ //多图导出
$num = 10;
$images = explode(',', $value);
foreach ($images as $k => $v) {
$drawings[$k] = new Drawing();
$img = self::img_resource(trim($v),$path,$k);
//图片路径,项目目录下就行
$drawings[$k]->setResizeProportional(false);
$drawings[$k]->setName('手动签名图片');
$drawings[$k]->setDescription('手动签名图片展示');
$drawings[$k]->setPath($img,true);
$drawings[$k]->setWidth(60);
$drawings[$k]->setHeight(60);
$drawings[$k]->setOffsetX($num);
$drawings[$k]->setOffsetY(10);
$drawings[$k]->setCoordinates($dataCol . $row);
$drawings[$k]->setWorksheet($sheet);
$num = $num + 70; // 增加每张图之间的间距
}
}else{
$sheet->setCellValue($dataCol . $row, $value);
}
//自适应列宽
$len = strlen($value);
if($len>1){ //空数据不做处理避免影响到有数据的列宽度
$sheet->getColumnDimension($dataCol)->setWidth($len);
}
$dataCol++;
}
$row++;
}
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
if(is_file($path.$file_name)){
file_put_contents($path.$file_name,'');;
}
$writer->save($path.$file_name);
return ['code'=>0,'url'=>trim($path.$file_name,'.')];
}catch (\Exception $e){
return ['code'=>1,'msg'=>$e->getMessage()];
}
}
/**
* 图片缓存到本地
* @param $url string 远程图片地址
* @param $dir string 本地缓存目录
* @param $i int 图片序号
* @return mixed
*/
public static function img_resource($url,$dir,$i){
$data = file_get_contents($url);
$path = $dir.time().'-'.$i;
file_put_contents($path, $data);
return $path;
}
}
```
效果:
![](https://img.kancloud.cn/5b/3b/5b3b9d55cef0d47c84ec875a4a674aac_950x527.png)
![](https://img.kancloud.cn/d9/99/d999be31c8dbb797c0953e1b00dc548a_886x352.png)
- Golang
- Beego框架
- Gin框架
- gin框架介绍
- 使用Gin web框架的知名开源线上项目
- go-admin-gin
- air 热启动
- 完整的form表单参数验证语法
- Go 语言入门练手项目推荐
- Golang是基于多线程模型
- golang 一些概念
- Golang程序开发注意事项
- fatal error: all goroutines are asleep - deadlock
- defer
- Golang 的内建调试器
- go部署
- golang指针重要性
- 包(golang)
- Golang框架选型比较: goframe, beego, iris和gin
- GoFrame
- golang-admin-项目
- go module的使用方法及原理
- go-admin支持多框架的后台系统(go-admin.cn)
- docker gocv
- go-fac
- MSYS2
- 企业开发框架系统推荐
- gorm
- go-zero
- 优秀系统
- GinSkeleton(gin web 及gin 知识)
- 一次 request -> response 的生命周期概述
- 路由与路由组以及gin源码学习
- 中间件以及gin源码学习
- golang项目部署
- 独立部署golang
- 代理部署golang
- 容器部署golang
- golang交叉编译
- goravel
- kardianos+gin 项目作为windows服务运行
- go env
- 适用在Windows、Linux和macOS环境下打包Go应用程序的详细步骤和命令
- Redis
- Dochub
- Docker部署开发go环境
- Docker部署运行go环境
- dochub说明
- Vue
- i18n
- vue3
- vue3基本知识
- element-plus 表格单选
- vue3后台模板
- Thinkphp
- Casbin权限控制中间件
- 容器、依赖注入、门面、事件、中间件
- tp6问答
- 伪静态
- thinkphp-queue
- think-throttle
- thinkphp队列queue的一些使用说明,queue:work和queue:listen的区别
- ThinkPHP6之模型事件的触发条件
- thinkphp-swoole
- save、update、insert 的区别
- Socket
- workerman
- 介绍
- 从ThinkPHP6移植到Webman的一些技术和经验(干货)
- swoole
- swoole介绍
- hyperf
- hf官网
- Swoft
- swoft官网
- easyswoole
- easyswoole官网地址
- EASYSWOOLE 聊天室DEMO
- socket问答
- MySQL
- 聚簇索引与非聚簇索引
- Mysql使用max获取最大值细节
- 主从复制
- 随机生成20万User表的数据
- MySQL进阶-----前缀索引、单例与联合索引
- PHP
- 面向切面编程AOP
- php是单线程的一定程度上也可以看成是“多线程”
- PHP 线程,进程、并发、并行 的理解
- excel数据画表格图片
- php第三方包
- monolog/monolog
- league/glide
- 博客-知识网站
- php 常用bc函数
- PHP知识点的应用场景
- AOP(面向切面编程)
- 注解
- 依赖注入
- 事件机制
- phpspreadsheet导出数据和图片到excel
- Hyperf
- mineAdmin
- 微服务
- nacos注册服务
- simps-mqtt连接客户端simps
- Linux
- 切换php版本
- Vim
- Laravel
- RabbitMQ
- thinkphp+rabbitmq
- 博客
- Webman框架
- 框架注意问题
- 关于内存泄漏
- 移动端自动化
- 懒人精灵
- 工具应用
- render
- gitlab Sourcetree
- ssh-agent失败 错误代码-1
- 资源网站
- Git
- wkhtmltopdf
- MSYS2 介绍
- powershell curl 使用教程
- NSSM(windows服务工具)
- MinGW64
- 知识扩展
- 对象存储系统
- minio
- 雪花ID
- 请求body参数类型
- GraphQL
- js 深拷贝
- window 共享 centos文件夹
- 前端get/post 请求 特殊符号 “+”传参数问题
- 什么是SCM系统?SCM系统与ERP系统有什么区别?
- nginx 日志格式统一为 json
- 特殊符号怎么打
- 收藏网址
- 收藏-golang
- 收藏-vue3
- 收藏-php
- 收藏-node
- 收藏-前端
- 规划ITEM
- 旅游类
- 人脸识别
- dlib
- Docker&&部署
- Docker-compose
- Docker的网络模式
- rancher
- DHorse
- Elasticsearch
- es与kibana都docke连接
- 4种数据同步到Elasticsearch方案
- GPT
- 推荐系统
- fastposter海报生成
- elasticsearch+logstash+kibana
- beego文档系统-MinDoc
- jeecg开源平台
- Java
- 打包部署
- spring boot
- 依赖
- Maven 相关 命令
- Gradle 相关命令
- mybatis
- mybatis.plus
- spring boot 模板引擎
- SpringBoot+Maven多模块项目(创建、依赖、打包可执行jar包部署测试)完整流程
- Spring Cloud
- Sentinel
- nacos
- Apollo
- java推荐项目
- gradle
- Maven
- Nexus仓库管理器
- Python
- Masonite框架
- scrapy
- Python2的pip2
- Python3 安装 pip3
- 安全攻防
- 运维技术
- 腾讯云安全加固建议
- 免费freessl证书申请
- ruby
- homeland
- Protobuf
- GIT
- FFMPEG
- 命令说明
- 音频
- ffmpeg合并多个MP4视频
- NODEJS
- 开发npm包
- MongoDB
- php-docker-mongodb环境搭建
- mongo基本命令
- Docker安装MongoDB最新版并连接
- 少儿编程官网
- UI推荐
- MQTT
- PHP连接mqtt
- EMQX服务端
- php搭建mqtt服务端