背景
-
最近有一个需求,需要将所有excel文件的sheet合并到一个文件。
-
目前我们处理表格使用的是xlswriter这个插件,对于数据量比较大的话非常好用。
-
但是呢,如果是合并文件的话就没有提供太多的方法,并且呢,只能实现数据层面的复制,没办法实现到图片或者单元格格式的复制。还有就是只能对xlsx格式进行读取和操作,对于xls格式的话就不是很友好,直接open file failed。
-
目前是需要全量备份,查阅了全网,匹配的插件也很少。当尝试到phpSpreadsheet时,发现它竟然可以实现全量复制,完美兼容所有excel格式。
参考文献
参考代码
传入参数
参数 | 介绍 | 是否必传 | 数据类型 |
---|
files | 需合并的所有excel文件的绝对路径 | 是 | array |
save_path | 合并后文件的绝对路径 | 是 | string |
save_name | 保存的文件名+后缀 | 否 | string |
<?php
namespace App\Services\Backend;
class ExcelService
{
/**
* Merge all excel's sheets and rename the name of sheet except the first one.
* @param $files array the paths of excel which need merge
* @param $save_path string the path of save
* @param $save_name string the name of save
* @return bool
*/
public function MergeAll($files, $save_path, $save_name = null)
{
if (!is_array($files) || empty($files) || empty($save_path)) return false;
try {
if(!file_exists($save_path)){
@mkdir($save_path, 0777, true);
}
if (is_null($save_name) || empty($save_name)){
$save_name = $this->random_letters(8) . ".xlsx";
}
// Create new table
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
// Merge all
foreach ($files as $kSort => $file) {
$excelObject = \PhpOffice\PhpSpreadsheet\IOFactory::load($file);
$sheet_arr = $excelObject->getSheetNames();
if (!empty($sheet_arr)) {
foreach ($sheet_arr as $key => $val) {
$sheet_name = "8.1.{$kSort}【{$key}】{$val}";
$sheet_name = mb_substr($sheet_name, 0, 31, "utf-8");
$sheet_name = $kSort == 0 ? $val : $sheet_name;
$newWorksheet = clone $excelObject->getSheetByName($val)->setTitle($sheet_name);
$spreadsheet->addExternalSheet($newWorksheet);
}
}
}
//Delete tabel which is blank
$sheetIndex = $spreadsheet->getIndex(
$spreadsheet->getSheetByName('Worksheet')
);
$spreadsheet->removeSheetByIndex($sheetIndex);
// Save
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xlsx');
// $writer = new Xlsx($spreadsheet);
$writer->save("{$save_path}/{$save_name}");
return true;
} catch (\Exception $e) {
throw new \Exception("合并表格失败:{$e->getMessage()}", "40300");
}
}
private function random_letters($length = 8) {
$letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
return substr(str_shuffle(str_repeat($letters, $length)), 0, $length);
}
}