Создание товарной накладной в PHPExcel

Подключение PHPExcel
require_once __DIR__ . '/PHPExcel/Classes/PHPExcel.php';
require_once __DIR__ . '/PHPExcel/Classes/PHPExcel/Writer/Excel2007.php';Создание экземпляра класса PHPExcel
$xls = new PHPExcel();Запись в первый лист
$xls->setActiveSheetIndex(0);
$sheet = $xls->getActiveSheet();Ширина задается в количестве символов
$sheet->getColumnDimension('A')->setWidth(12);
$sheet->getColumnDimension('B')->setWidth(17);
$sheet->getColumnDimension('C')->setWidth(60);
$sheet->getColumnDimension('D')->setWidth(10);
$sheet->getColumnDimension('E')->setWidth(6);
$sheet->getColumnDimension('F')->setWidth(10);
$sheet->getColumnDimension('G')->setWidth(10);Создается переменная $line, в ней будет считаться номер строки
$line = 1;
$sheet->setCellValue("A{$line}", 'Товарная накладная № 1 от ' . date('d.m.Y H:i'));Объединение ячейки по горизонтали
$sheet->mergeCells("A{$line}:G{$line}");Выравнивание по центру вертикали и горизонтали
$sheet->getStyle("A{$line}")->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
$sheet->getStyle("A{$line}")->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER);Текст жирным и увеличение шрифта
$sheet->getStyle("A{$line}")->getFont()->setBold(true);
$sheet->getStyle("A{$line}")->getFont()->setSize(18);Пропуск строки после заголовка
$line++;
$sheet->setCellValue("A{$line}", '');
$sheet->mergeCells("A{$line}:G{$line}");Информация о поставщике
$line++;
$sheet->setCellValue("A{$line}", 'Поставщик:');
$sheet->setCellValue("B{$line}", htmlspecialchars_decode('ООО Рога'));
$sheet->getStyle("B{$line}")->getFont()->setBold(true);
$sheet->mergeCells("B{$line}:G{$line}");
 
$line++;
$sheet->setCellValue("B{$line}", 'Адрес: г. Москва, ул. Тверская, д.24, тел: 8 (923) 123-45-67'); 
$sheet->mergeCells("B{$line}:G{$line}");Информация о покупателе
$line++;
$sheet->setCellValue("A{$line}", 'Покупатель:');
$sheet->setCellValue("B{$line}", 'Иванов Иван Иванович');
$sheet->getStyle("B{$line}")->getFont()->setBold(true);
$sheet->mergeCells("B{$line}:G{$line}");
 
$line++;
$sheet->setCellValue("B{$line}", 'Тел 9 (999) 999-99-99');
$sheet->mergeCells("B{$line}:G{$line}");Пропуск строки
$line++;
$start_table = $line;Шапка таблицы
$sheet->setCellValue("A{$line}", 'п/п');
$sheet->setCellValue("B{$line}", 'Артикул');
$sheet->setCellValue("C{$line}", 'Название');
$sheet->setCellValue("D{$line}", 'Кол-во');
$sheet->setCellValue("E{$line}", 'Ед.');
$sheet->setCellValue("F{$line}", 'Цена');
$sheet->setCellValue("G{$line}", 'Сумма');Стили для текста в шапки таблицы
$sheet->getStyle("A{$line}:G{$line}")->getFont()->setBold(true); 
$sheet->getStyle("A{$line}:G{$line}")->getAlignment()->setWrapText(true);
$sheet->getStyle("A{$line}:G{$line}")->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
$sheet->getStyle("A{$line}:G{$line}")->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER);Пример товаров представлен в виде массива
$prods = array(
	array(
		'sku'   => '8545775',
		'name'  => 'Боксерские перчатки GREEN HILL Super Star (без марки AIBA)',
		'price' => '6060',
		'count' => '2'
	),
	array(
		'sku'   => '865645',
		'name'  => 'Боксерский мешок 120X35, 46 кг',
		'price' => '9900',
		'count' => '1'
	),
	array(
		'sku'   => '865643',
		'name'  => 'Кронштейн для боксерского мешка',
		'price' => '4800',
		'count' => '3'
	),
);Вывод товаров в цикле
foreach ($prods as $i => $prod) {
	$line++;
	$sheet->setCellValue("A{$line}", ++$i);
	$sheet->setCellValue("B{$line}", $prod['sku']);
	$sheet->setCellValue("C{$line}", $prod['name']);
	$sheet->setCellValue("D{$line}", $prod['count']);
	$sheet->setCellValue("E{$line}", 'шт.');
	$sheet->setCellValue("F{$line}", number_format($prod['price'], 2, ',', ' '));
	$sheet->setCellValue("G{$line}", number_format($prod['price'] * $prod['count'], 2, ',', ' '));
 
	// Выравнивание текста в ячейках.
	$sheet->getStyle("A{$line}")->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
	$sheet->getStyle("B{$line}")->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
	$sheet->getStyle("C{$line}")->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
	$sheet->getStyle("D{$line}")->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);
	$sheet->getStyle("E{$line}")->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
	$sheet->getStyle("F{$line}")->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);
	$sheet->getStyle("G{$line}")->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);
 
	// Подсчет "Итого".
	@$total += $prod['price'] * $prod['count'];
}Рамка к таблице
$sheet->getStyle("A{$start_table}:G{$line}")->applyFromArray(
	array(
		'borders' => array(
			'allborders' => array(
				'style' => PHPExcel_Style_Border::BORDER_THIN
			)
		)
	)
);Итого
$line++;
$sheet->setCellValue("A{$line}", 'Итого:');
$sheet->mergeCells("A{$line}:F{$line}");
 
$sheet->setCellValue("G{$line}", number_format($total, 2, ',', ' '));
$sheet->getStyle("A{$line}:G{$line}")->getFont()->setBold(true);
$sheet->getStyle("A{$line}:G{$line}")->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);НДС (20% от итого)
$line++;
$sheet->setCellValue("A{$line}", 'В том числе НДС:');
$sheet->mergeCells("A{$line}:F{$line}");
 
$sheet->setCellValue("G{$line}", number_format(($total / 100) * 20, 2, ',', ' '));
$sheet->getStyle("A{$line}:G{$line}")->getFont()->setBold(true);
$sheet->getStyle("A{$line}:G{$line}")->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);Всего наименований
$line++;
$sheet->setCellValue(
	"A{$line}",
	'Всего наименований ' . count($prods) . ', на сумму ' . number_format($total, 2, ',', ' ') . ' руб.'
);
$sheet->mergeCells("A{$line}:G{$line}");Сумма прописью
Здесь используется функция num2str() для получение суммы прописью, взято с https://habrahabr.ru/post/53210/.
Посмотреть скрипт функции num2str() на данном сайте
У суммы прописью сделать первую букву заглавной. Т.к. скрипт в UTF-8 функция ucfirst не работает, поэтому используется аналог – mb_ucfirst().
$line++;
$sheet->setCellValue("A{$line}", mb_ucfirst(num2str($total)));
$sheet->getStyle("A{$line}")->getFont()->setBold(true);
$sheet->mergeCells("A{$line}:G{$line}");Отдача файла браузеру на скачивание
header("Expires: Mon, 1 Apr 1974 05:00:00 GMT");
header("Last-Modified: " . gmdate("D,d M YH:i:s") . " GMT");
header("Cache-Control: no-cache, must-revalidate");
header("Pragma: no-cache");
header("Content-type: application/vnd.ms-excel" );
header("Content-Disposition: attachment; filename=order.xlsx");
 
$objWriter = new PHPExcel_Writer_Excel2007($xls);
$objWriter->save('php://output');Или сохранить на сервере
$objWriter = new PHPExcel_Writer_Excel2007($xls);
$objWriter->save(__DIR__ . '/order.xlsx');Источник: https://snipp.ru/php/waybill-phpexcel