SpreadsheetExcelService.php 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. <?php
  2. namespace crmeb\services;
  3. class SpreadsheetExcelService
  4. {
  5. //
  6. private static $instance = null;
  7. //PHPSpreadsheet实例化对象
  8. private static $spreadsheet = null;
  9. //sheet实例化对象
  10. private static $sheet = null;
  11. private static $createsheet = null;
  12. //表头计数
  13. protected static $count;
  14. //表头占行数
  15. protected static $topNumber = 3;
  16. //表能占据表行的字母对应self::$cellkey
  17. protected static $cells;
  18. //表头数据
  19. protected static $data = [];
  20. //文件名
  21. protected static $title = '订单导出';
  22. //行宽
  23. protected static $width = 20;
  24. //行高
  25. protected static $height = 50;
  26. //保存文件目录
  27. protected static $path = 'phpExcel/';
  28. //设置style
  29. private static $styleArray = [
  30. // 'borders' => [
  31. // 'allBorders' => [
  32. // // PHPExcel_Style_Border里面有很多属性,想要其他的自己去看
  33. // // 'style' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THICK,//边框是粗的
  34. // // 'style' => \PHPExcel_Style_Border::BORDER_DOUBLE,//双重的
  35. // // 'style' => \PHPExcel_Style_Border::BORDER_HAIR,//虚线
  36. // // 'style' => \PHPExcel_Style_Border::BORDER_MEDIUM,//实粗线
  37. // // 'style' => \PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT,//虚粗线
  38. // // 'style' => \PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT,//点虚粗线
  39. // 'style' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,//细边框
  40. // // 'color' => ['argb' => 'FFFF0000'],
  41. // ],
  42. // ],
  43. 'font' => [
  44. 'bold' => true
  45. ],
  46. 'alignment' => [
  47. 'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
  48. 'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER
  49. ]
  50. ];
  51. private function __construct(){}
  52. private function __clone(){}
  53. public static function instance()
  54. {
  55. if (self::$instance === null) {
  56. self::$instance = new self();
  57. self::$spreadsheet = $spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
  58. }
  59. return self::$instance;
  60. }
  61. public static function instance_xin()
  62. {
  63. self::$instance = new self();
  64. self::$spreadsheet = $spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
  65. return self::$instance;
  66. }
  67. public function createOrActive($i = null)
  68. {
  69. if($i){
  70. self::$sheet = self::$spreadsheet->createSheet();
  71. }else{
  72. self::$sheet = self::$spreadsheet->getActiveSheet();
  73. }
  74. return $this;
  75. }
  76. /**
  77. *设置字体格式
  78. * @param $title string 必选
  79. * return string
  80. */
  81. public static function setUtf8($title)
  82. {
  83. return iconv('utf-8', 'gb2312', $title);
  84. }
  85. /**
  86. * 创建保存excel目录
  87. * return string
  88. */
  89. public static function savePath()
  90. {
  91. if(!is_dir(self::$path)){
  92. if (mkdir(self::$path, 0700) == false) {
  93. return false;
  94. }
  95. }
  96. //年月一级目录
  97. $mont_path = self::$path.date('Ym');
  98. if(!is_dir($mont_path)){
  99. if (mkdir($mont_path, 0700) == false) {
  100. return false;
  101. }
  102. }
  103. //日二级目录
  104. $day_path = $mont_path.'/'.date('d');
  105. if(!is_dir($day_path)){
  106. if (mkdir($day_path, 0700) == false) {
  107. return false;
  108. }
  109. }
  110. return $day_path;
  111. }
  112. /**
  113. * 设置标题
  114. * @param $title string || array ['title'=>'','name'=>'','info'=>[]]
  115. * @param $Name string
  116. * @param $info string || array;
  117. * @param $funName function($style,$A,$A2) 自定义设置头部样式
  118. * @return $this
  119. */
  120. public function setExcelTile($title = '', $Name = '', $info = [], $funName = null)
  121. {
  122. //设置参数
  123. if (is_array($title)) {
  124. if (isset($title['title'])) $title = $title['title'];
  125. if (isset($title['name'])) $Name = $title['name'];
  126. if (isset($title['info'])) $info = $title['info'];
  127. }
  128. if (empty($title))
  129. $title = self::$title;
  130. else
  131. self::$title = $title;
  132. if (empty($Name)) $Name = time();
  133. //设置Excel属性
  134. self::$spreadsheet->getProperties()
  135. ->setCreator("Neo")
  136. ->setLastModifiedBy("Neo")
  137. ->setTitle(self::setUtf8($title))
  138. ->setSubject($Name)
  139. ->setDescription("")
  140. ->setKeywords($Name)
  141. ->setCategory("");
  142. self::$sheet->setTitle($Name);
  143. self::$sheet->setCellValue('A1', $title);
  144. self::$sheet->setCellValue('A2', self::setCellInfo($info));
  145. //文字居中
  146. self::$sheet->getStyle('A1')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  147. self::$sheet->getStyle('A2')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  148. //合并表头单元格
  149. self::$sheet->mergeCells('A1:' . self::$cells . '1');
  150. self::$sheet->mergeCells('A2:' . self::$cells . '2');
  151. self::$sheet->getRowDimension(1)->setRowHeight(40);
  152. self::$sheet->getRowDimension(2)->setRowHeight(20);
  153. //设置表头字体
  154. self::$sheet->getStyle('A1')->getFont()->setName('黑体');
  155. self::$sheet->getStyle('A1')->getFont()->setSize(20);
  156. self::$sheet->getStyle('A1')->getFont()->setBold(true);
  157. self::$sheet->getStyle('A2')->getFont()->setName('宋体');
  158. self::$sheet->getStyle('A2')->getFont()->setSize(14);
  159. self::$sheet->getStyle('A2')->getFont()->setBold(true);
  160. self::$sheet->getStyle('A3:' . self::$cells . '3')->getFont()->setBold(true);
  161. return $this;
  162. }
  163. /**
  164. * 设置第二行标题内容
  165. * @param $info array (['name'=>'','site'=>'','phone'=>123] || ['我是表名','我是地址','我是手机号码'] ) || string 自定义
  166. * @return string
  167. */
  168. private static function setCellInfo($info)
  169. {
  170. $content = ['操作者:', '导出日期:' . date('Y-m-d', time()), '地址:', '电话:'];
  171. if (is_array($info) && !empty($info)) {
  172. if (isset($info['name'])) {
  173. $content[0] .= $info['name'];
  174. } else {
  175. $content[0] .= isset($info[0]) ? $info[0] : '';
  176. }
  177. if (isset($info['site'])) {
  178. $content[2] .= $info['site'];
  179. } else {
  180. $content[2] .= isset($info[1]) ? $info[1] : '';
  181. }
  182. if (isset($info['phone'])) {
  183. $content[3] .= $info['phone'];
  184. } else {
  185. $content[3] .= isset($info[2]) ? $info[2] : '';
  186. }
  187. return implode(' ', $content);
  188. } else if (is_string($info)) {
  189. return empty($info) ? implode(' ', $content) : $info;
  190. }
  191. }
  192. /**
  193. * 设置头部信息
  194. * @param $data array
  195. * @return $this
  196. */
  197. public function setExcelHeader($data)
  198. {
  199. $span = 'A';
  200. foreach ($data as $key => $value) {
  201. self::$sheet->getColumnDimension($span)->setWidth(self::$width);
  202. self::$sheet->setCellValue($span.self::$topNumber, $value);
  203. $span++;
  204. }
  205. self::$sheet->getRowDimension(3)->setRowHeight(self::$height);
  206. self::$cells = $span;
  207. return $this;
  208. }
  209. /**
  210. *
  211. * execl数据导出
  212. * @param $data 需要导出的数据 格式和以前的可是一样
  213. *
  214. * 特殊处理:合并单元格需要先对数据进行处理
  215. */
  216. public function setExcelContent($data = [])
  217. {
  218. if (!empty($data) && is_array($data)) {
  219. $column = self::$topNumber+1;
  220. // 行写入
  221. foreach ($data as $key => $rows) {
  222. $span = 'A';
  223. // 列写入
  224. foreach ($rows as $keyName => $value) {
  225. self::$sheet->setCellValue($span . $column, $value);
  226. $span++;
  227. }
  228. $column++;
  229. }
  230. self::$sheet->getDefaultRowDimension()->setRowHeight(self::$height);
  231. //设置内容字体样式
  232. self::$sheet->getStyle('A1:' . $span.$column)->applyFromArray(self::$styleArray);
  233. //设置边框
  234. self::$sheet->getStyle('A1:' . $span.$column)->getBorders()->getAllBorders()->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN);
  235. //设置自动换行
  236. self::$sheet->getStyle('A4:' . $span.$column)->getAlignment()->setWrapText(true);
  237. }
  238. return $this;
  239. }
  240. /**
  241. * 保存表格数据
  242. * @param $filename 文件名称
  243. * @param $suffix 文件后缀名
  244. * @param $path 是否保存文件文件
  245. * @return 保存文件:return string
  246. */
  247. public function excelSave($fileName = '',$suffix = 'xlsx',$path)
  248. {
  249. if(empty($fileName)) $fileName = date('YmdHis').time();
  250. if(empty($suffix)) $suffix = 'xlsx';
  251. // 重命名表(UTF8编码不需要这一步)
  252. if (mb_detect_encoding($fileName) != "UTF-8") $fileName = iconv("utf-8", "gbk//IGNORE", $fileName);
  253. $save_path = self::$path.$path;
  254. $root_path = app()->getRootPath().'public/'.$save_path;
  255. if(!is_dir($root_path)) mkdir($root_path, 0700,true);
  256. $spreadsheet = self::$spreadsheet;
  257. $writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
  258. $writer->save($root_path.'/'.$fileName.'.'.$suffix);
  259. return $save_path.'/'.$fileName.'.'.$suffix;
  260. }
  261. }