Создание товарной накладной в 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