最近接手一个新项目。但是客户给过来的代码。excel做成出来的文件无论如何都不好用。经过一番调查。发现这个项目的excel做成方式很特别。特,记载一下,以防自己忘记
在介绍这个做成excel之前,首先得excel文件的组成
详情看下面的连接。我就不介绍了
https://blog.csdn.net/hejingyuan6/article/details/79044256
知道这个原理之后,我们就按照这个原理反向。就可以做成一个excel文件了
将,解压生成的几个文件copy到工程目录下
这里会用到 ZipStream-PHP
public function export(Request $request, ExcelStream $stream)
{
// $query = $this->getQuery($request)->with([
// // current=1を優先、qualificationidの昇順で最初の1件を取得
// 'wgusers' => function ($q) { $q->orderBy('current', 'desc')->orderBy('qualificationid', 'asc'); }
// ]);
$query = $this->getQuery($request);
/* ->with([
// current=1を優先、qualificationidの昇順で最初の1件を取得
'wgusers' => function ($q) { $q->orderBy('current', 'desc')->orderBy('qualificationid', 'asc'); }
]);*/
set_time_limit(0);
$headers = [
'loginid' => 'ログインID',
'lastname' => '姓',
'firstname' => '名',
'lastkana' => '姓フリガナ',
'firstkana' => '名フリガナ',
'sex' => '性別',
'officename' => '所属',
'title' => '職種',
'zipcode' => '勤務先郵便番号',
'pref' => '勤務先都道府県',
'address1' => '勤務先住所',
'address2' => 'ビル名等',
'phone' => '緊急連絡先電話番号',
'provider' => 'プロバイダー番号',
'instructor' => 'インストラクター番号',
'email' => 'メールアドレス',
'active' => '学習者権限',
'admin' => '事務局権限',
'potential' => '現在の資格',
];
return $stream->stream([
'basename' => 'users',
'sheetname' => 'ユーザー情報',
'headers' => array_values($headers),
], function ($callback) use ($query) {
$query->chunk(10, function ($chunk) use ($callback) {
foreach ($chunk as $user) {
try {
$callback([
$user->loginid,
$user->lastname,
$user->firstname,
$user->lastkana,
$user->firstkana,
$user->gender,
$user->officename,
$user->title,
$user->zipcode,
\App\Prefs::getName($user->pref ?? 0),
$user->address1,
$user->address2,
$user->phone,
$user->provider,
$user->instructor,
$user->email,
$user->active ? '○' : '',
$user->isAdmin() ? '○' : '',
array_get(User::POTENTIALS, $user->potential ?? 0),
]);
} catch (Exception $e) { Log::error($e); }
}
});
});
}
public function stream($param, $callback)
{
try {
return response()->stream(function () use ($param, $callback) {
$zip = app(ZipStream::class);
// 不変のファイルを格納
foreach (self::getFiles(resource_path('xlsx')) as $path => $file) {
$zip->addFileFromPath($path, $file);
}
// workbook.xmlをストリーム生成
$zip->addFileFromCallback('xl/workbook.xml', function ($sender) use ($param) {
$workbook = simplexml_load_string(self::EXCEL_WORKBOOK);
$workbook->sheets->sheet['name'] = $param['sheetname'] ? $param['sheetname'] : 'Sheet1';
$sender($workbook->asXML());
});
// sheet1.xmlをストリーム生成
$zip->addFileFromCallback('xl/worksheets/sheet1.xml', function ($sender) use ($param, $callback) {
$sender(self::EXCEL_SHEET_HEADER);
// ヘッダ行
$sender('<row r="1">');
foreach ($param['headers'] as $column => $value) {
$sender(self::getColumnXml(1, $column, $value));
}
$sender('</row>');
$index = 2;
$callback(function ($row) use ($sender, & $index) {
$sender("<row r=\"$index\">");
foreach ($row as $column => $value) {
$sender(self::getColumnXML($index, $column, $value));
}
$sender('</row>');
$index++;
});
$sender(self::EXCEL_SHEET_FOOTER);
});
$zip->finish();
}, 200, [
'Content-disposition' => 'attachment; filename="' . $param['basename'] . '.xlsx"',
'Content-type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=UTF-8',
]);
} catch (Exception $e) {
return $this->errorResponse($e);
}
}
原理就是依次读取这几个文件。放到一个zip流中。最后,强行转成xlsx格式