From c73910ba74f5dea293e2fcd185b8a4493dc03765 Mon Sep 17 00:00:00 2001 From: xinen <2302563948@qq.com> Date: Sun, 1 Nov 2026 16:17:12 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B4=A6=E5=8D=95=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Exports/BillExport.php | 4 +++- app/Exports/ContainerReturnExport.php | 4 +++- app/Exports/PurchaseOrderExport.php | 3 ++- app/Exports/PurchaseStoreSheet.php | 3 ++- app/Exports/PurchaseSupplierSheet.php | 11 ++++++----- tests/Feature/BillExportTest.php | 12 ++++++++++++ tests/Feature/ContainerReturnTest.php | 17 +++++++++++++++++ tests/Feature/ExportTest.php | 24 ++++++++++++++++++++++++ 8 files changed, 69 insertions(+), 9 deletions(-) diff --git a/app/Exports/BillExport.php b/app/Exports/BillExport.php index 0c099d5..cc380da 100644 --- a/app/Exports/BillExport.php +++ b/app/Exports/BillExport.php @@ -240,7 +240,7 @@ class BillExport implements FromCollection, WithStyles, WithTitle } /** - * 标题/列头/合计行加粗,合计行标签左合并 A:G;全表居中 + 全边框;金额列货币格式; + * 标题合并 A:H 并居中;标题/列头/合计行加粗,合计行标签左合并 A:G;全表居中 + 全边框;金额列货币格式; * 数量(浅黄)/金额(浅红)非 0 条件填色(0 不填、列头固定填色),冻结列头 */ public function styles(Worksheet $sheet): array @@ -257,6 +257,8 @@ class BillExport implements FromCollection, WithStyles, WithTitle $sheet->getColumnDimension('G')->setWidth(12); $sheet->getColumnDimension('H')->setWidth(12); + $sheet->mergeCells('A1:H1'); + foreach ($this->mergeRows as $row) { $sheet->mergeCells('A' . $row . ':G' . $row); } diff --git a/app/Exports/ContainerReturnExport.php b/app/Exports/ContainerReturnExport.php index 3be286f..9a42703 100644 --- a/app/Exports/ContainerReturnExport.php +++ b/app/Exports/ContainerReturnExport.php @@ -144,7 +144,7 @@ class ContainerReturnExport implements FromCollection, WithStyles, WithStrictNul } /** - * 标题/列头/合计行加粗;全表居中 + 全边框;金额区货币格式; + * 标题按实际列数合并居中;标题/列头/合计行加粗;全表居中 + 全边框;金额区货币格式; * 门店列(浅蓝)/合计列(浅红)非 0 条件填色(0 不填、列头固定填色),冻结列头行 */ public function styles(Worksheet $sheet): array @@ -161,6 +161,8 @@ class ContainerReturnExport implements FromCollection, WithStyles, WithStrictNul $storeIds = array_map(intval(...), array_keys($this->storeNames)); $lastColumn = Coordinate::stringFromColumnIndex($columnCount); + $sheet->mergeCells('A1:' . $lastColumn . '1'); + // 全部单元格水平/垂直居中 $sheet->getStyle('A1:' . $lastColumn . $this->lastRow) ->getAlignment() diff --git a/app/Exports/PurchaseOrderExport.php b/app/Exports/PurchaseOrderExport.php index 985ee2c..431414f 100644 --- a/app/Exports/PurchaseOrderExport.php +++ b/app/Exports/PurchaseOrderExport.php @@ -252,7 +252,7 @@ class PurchaseOrderExport implements FromCollection, WithStrictNullComparison, W } /** - * 标题/列头/合计加粗;全表居中 + 全边框;金额类列货币格式; + * 标题按实际列数合并居中;标题/列头/合计加粗;全表居中 + 全边框;金额类列货币格式; * 数量(浅黄)/门店数量(浅蓝)/金额(浅红)按值条件填色(0 不填、列头固定填色),冻结列头 */ public function styles(Worksheet $sheet): array @@ -279,6 +279,7 @@ class PurchaseOrderExport implements FromCollection, WithStrictNullComparison, W } // 全部单元格水平/垂直居中 + $sheet->mergeCells('A1:' . $lastColumn . '1'); $sheet->getStyle('A1:' . $lastColumn . $this->lastRow) ->getAlignment() ->setHorizontal(Alignment::HORIZONTAL_CENTER) diff --git a/app/Exports/PurchaseStoreSheet.php b/app/Exports/PurchaseStoreSheet.php index 2bbea62..c5633f3 100644 --- a/app/Exports/PurchaseStoreSheet.php +++ b/app/Exports/PurchaseStoreSheet.php @@ -120,7 +120,7 @@ class PurchaseStoreSheet implements FromCollection, WithStrictNullComparison, Wi } /** - * 标题/列头/合计加粗;全表居中 + 全边框;金额类列货币格式; + * 标题合并 A:I 并居中;标题/列头/合计加粗;全表居中 + 全边框;金额类列货币格式; * 数量(浅黄)/金额(浅红)按值条件填色(0 不填、列头固定填色),冻结列头 */ public function styles(Worksheet $sheet): array @@ -135,6 +135,7 @@ class PurchaseStoreSheet implements FromCollection, WithStrictNullComparison, Wi } // 全部单元格水平/垂直居中 + $sheet->mergeCells('A1:I1'); $sheet->getStyle('A1:I' . $this->lastRow) ->getAlignment() ->setHorizontal(Alignment::HORIZONTAL_CENTER) diff --git a/app/Exports/PurchaseSupplierSheet.php b/app/Exports/PurchaseSupplierSheet.php index 5334731..2abcf1e 100644 --- a/app/Exports/PurchaseSupplierSheet.php +++ b/app/Exports/PurchaseSupplierSheet.php @@ -122,7 +122,7 @@ class PurchaseSupplierSheet implements FromCollection, WithStrictNullComparison, } /** - * 标题合并 A1:C2、备注合并 D1:I2(红色 22 号字);标题/列头加粗;全表居中 + 全边框 + 列头行自动换行; + * 标题合并 A1:C2、备注从 D1 合并至实际末列(红色 22 号字);标题/列头加粗;全表居中 + 全边框 + 列头行自动换行; * 汇总列(浅黄)/门店数量列(浅蓝)按值条件填色(0 不填、列头固定填色),冻结列头 */ public function styles(Worksheet $sheet): array @@ -131,16 +131,17 @@ class PurchaseSupplierSheet implements FromCollection, WithStrictNullComparison, $sheet->freezePane('A' . ($this->headerRow + 1)); - // 标题合并前三列占两行(A1:C2),备注合并六列两行(D1:I2) - $sheet->mergeCells('A1:C2'); - $sheet->mergeCells('D1:I2'); - $widths = [24, 10, 6]; foreach ($widths as $index => $width) { $sheet->getColumnDimension(Coordinate::stringFromColumnIndex($index + 1))->setWidth($width); } $storeIds = array_map('intval', array_keys($this->stores)); $lastColumn = Coordinate::stringFromColumnIndex(3 + max(count($storeIds), 1)); + + // 标题占前三列,备注占其余实际表格列,均合并两行 + $sheet->mergeCells('A1:C2'); + $sheet->mergeCells('D1:' . $lastColumn . '2'); + foreach ($storeIds as $i => $storeId) { $sheet->getColumnDimension(Coordinate::stringFromColumnIndex(4 + $i))->setWidth(6); } diff --git a/tests/Feature/BillExportTest.php b/tests/Feature/BillExportTest.php index 56ef6d7..6197277 100644 --- a/tests/Feature/BillExportTest.php +++ b/tests/Feature/BillExportTest.php @@ -11,6 +11,7 @@ use App\Models\PurchaseOrderModel; use App\Models\StoreModel; use App\Models\StoreOrderItemModel; use Maatwebsite\Excel\Facades\Excel; +use PhpOffice\PhpSpreadsheet\Spreadsheet; /** * 门店账单导出:单账单合并明细 / 批量按门店分工作表 / 一级分类过滤 / @@ -139,6 +140,17 @@ class BillExportTest extends ProcurementTestCase ); } + /** 账单标题合并全部八列,避免标题受首列宽度限制 */ + public function test_export_title_is_merged_across_all_columns(): void + { + $bill = $this->makeBill(StoreModel::factory()->create()); + $sheet = (new Spreadsheet())->getActiveSheet(); + + (new BillExport($bill))->styles($sheet); + + $this->assertArrayHasKey('A1:H1', $sheet->getMergeCells()); + } + /** 批量导出:同一门店多账单的同商品与费用合并为一张表,不同门店拆分工作表 */ public function test_batch_export_groups_bills_by_store(): void { diff --git a/tests/Feature/ContainerReturnTest.php b/tests/Feature/ContainerReturnTest.php index 3670b3e..1d5f761 100644 --- a/tests/Feature/ContainerReturnTest.php +++ b/tests/Feature/ContainerReturnTest.php @@ -13,6 +13,7 @@ use App\Models\StoreOrderModel; use Illuminate\Support\Facades\DB; use Maatwebsite\Excel\Facades\Excel; use Modules\SystemTool\Services\SysSiteConfigService; +use PhpOffice\PhpSpreadsheet\Spreadsheet; /** * 压回筐记录:周转筐/托盘跟账单走(生成账单时写入完整快照,只读); @@ -243,6 +244,22 @@ class ContainerReturnTest extends ProcurementTestCase ); } + /** 汇总导出标题按日期、门店及合计列的总宽度合并 */ + public function test_export_title_is_merged_across_dynamic_columns(): void + { + $export = new ContainerReturnExport( + collect(), + [1 => '门店A', 2 => '门店B'], + '2026-08-01', + '2026-08-03', + ); + $sheet = (new Spreadsheet())->getActiveSheet(); + + $export->styles($sheet); + + $this->assertArrayHasKey('A1:D1', $sheet->getMergeCells()); + } + /** 指定门店导出:仅所选门店成列,未选门店记录忽略;所选门店无记录整列填 0 */ public function test_export_filters_by_selected_stores(): void { diff --git a/tests/Feature/ExportTest.php b/tests/Feature/ExportTest.php index b442e5d..58be4a7 100644 --- a/tests/Feature/ExportTest.php +++ b/tests/Feature/ExportTest.php @@ -216,6 +216,30 @@ class ExportTest extends ProcurementTestCase $this->assertSame(45.0, (float) $total[11]); } + /** 采购导出:标题按实际表格列合并,供应商备注区域随门店列数调整 */ + public function test_export_titles_are_merged_across_table_columns(): void + { + [$purchase] = $this->buildPurchaseWithSuppliers(); + + $purchaseSheet = (new Spreadsheet())->getActiveSheet(); + (new PurchaseOrderExport($purchase))->styles($purchaseSheet); + $this->assertArrayHasKey('A1:N1', $purchaseSheet->getMergeCells()); + + $storeSheet = (new Spreadsheet())->getActiveSheet(); + (new PurchaseStoreExport($purchase))->sheets()[0]->styles($storeSheet); + $this->assertArrayHasKey('A1:I1', $storeSheet->getMergeCells()); + + $supplierSheets = (new PurchaseSupplierExport($purchase))->sheets(); + $supplierSheetA = (new Spreadsheet())->getActiveSheet(); + $supplierSheets[0]->styles($supplierSheetA); + $this->assertArrayHasKey('A1:C2', $supplierSheetA->getMergeCells()); + $this->assertArrayHasKey('D1:E2', $supplierSheetA->getMergeCells()); + + $supplierSheetB = (new Spreadsheet())->getActiveSheet(); + $supplierSheets[1]->styles($supplierSheetB); + $this->assertArrayHasKey('D1:D2', $supplierSheetB->getMergeCells()); + } + /** 商品明细导出:范围=全部未删除商品(含下架)∪ 本采购单有订货商品;已删除且无订货的商品不导出 */ public function test_export_scope_includes_off_shelf_but_not_deleted(): void {