namespace yii_app\services;
-use PhpOffice\PhpSpreadsheet\Spreadsheet;
-use PhpOffice\PhpSpreadsheet\Style\Alignment;
-use PhpOffice\PhpSpreadsheet\Style\Fill;
-use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use Yii;
use yii\data\Pagination;
use yii\db\Expression;
}
/**
- * Экспорт маппинга в .xlsx с учётом фильтров.
+ * Экспорт маппинга в CSV с учётом фильтров.
*
* Формат: одна строка на пару (товар, маппинг).
* Товары без маппингов — отдельной строкой с пустыми полями маппинга.
+ * Кодировка UTF-8 BOM (Excel корректно открывает без настроек импорта).
*
* @return string Абсолютный путь к временному файлу (вызывающий обязан удалить)
*/
public function exportToXlsx(ProductMappingFilterForm $filters): string
{
- // Все товары по фильтрам (без пагинации)
$query = $this->buildFilteredQuery($filters)->orderBy(['n.name' => SORT_ASC]);
/** @var Products1cNomenclature[] $products */
array_map(static fn($p) => $p->id, $products)
);
- $spreadsheet = new Spreadsheet();
- $sheet = $spreadsheet->getActiveSheet();
- $sheet->setTitle('Маппинг товаров');
+ $runtimeDir = Yii::getAlias('@runtime');
+ if (!is_dir($runtimeDir)) {
+ mkdir($runtimeDir, 0775, true);
+ }
+ $path = $runtimeDir . '/product-mapping-export-' . date('YmdHis') . '-' . uniqid() . '.csv';
- $headers = [
+ $fh = fopen($path, 'w');
+ // BOM для корректного открытия в Excel
+ fwrite($fh, "\xEF\xBB\xBF");
+
+ fputcsv($fh, [
'GUID товара',
'Название товара 1С',
'Категория',
'Штрихкод',
'Квант',
'Маркировки (коды)',
- ];
- $sheet->fromArray($headers, null, 'A1');
-
- // Стиль заголовков: bold + серый фон
- $lastCol = $sheet->getHighestColumn();
- $sheet->getStyle("A1:{$lastCol}1")->getFont()->setBold(true);
- $sheet->getStyle("A1:{$lastCol}1")->getFill()
- ->setFillType(Fill::FILL_SOLID)
- ->getStartColor()->setRGB('E9ECEF');
- $sheet->getStyle("A1:{$lastCol}1")->getAlignment()->setVertical(Alignment::VERTICAL_CENTER);
- $sheet->freezePane('A2');
-
- $row = 2;
+ ], ';');
+
foreach ($products as $product) {
$mappings = $mappingsByGuid[$product->id] ?? [];
if (empty($mappings)) {
- $sheet->fromArray([
+ fputcsv($fh, [
$product->id,
$product->name,
$product->category ?? '',
$product->subcategory ?? '',
$product->species ?? '',
'', '', '', '', '', '', '',
- ], null, "A{$row}");
- $row++;
+ ], ';');
continue;
}
foreach ($mappings as $mapping) {
- $markingCodes = [];
- foreach ($mapping->markings as $m) {
- $markingCodes[] = $m->code;
- }
- $sheet->fromArray([
+ $markingCodes = array_map(static fn($m) => $m->code, $mapping->markings);
+ fputcsv($fh, [
$product->id,
$product->name,
$product->category ?? '',
$mapping->barcode ?? '',
(int)$mapping->quant,
implode(', ', $markingCodes),
- ], null, "A{$row}");
- $row++;
+ ], ';');
}
}
- // Авто-ширина колонок
- foreach (range('A', $lastCol) as $col) {
- $sheet->getColumnDimension($col)->setAutoSize(true);
- }
-
- $runtimeDir = Yii::getAlias('@runtime');
- if (!is_dir($runtimeDir)) {
- mkdir($runtimeDir, 0775, true);
- }
- $path = $runtimeDir . '/product-mapping-export-' . date('YmdHis') . '-' . uniqid() . '.xlsx';
-
- (new Xlsx($spreadsheet))->save($path);
- $spreadsheet->disconnectWorksheets();
- unset($spreadsheet);
+ fclose($fh);
return $path;
}