Товарный чек в формате xml (Excel)

Товарный чек в формате xml (Excel) (Битрикс)

Здравствуйте. Сегодня я расскажу о способе сделать в Битриксе печать документов в формате xml. В результате ваши формируемые документы будет не отличить от тех, которые есть в 1С УТ.

Расскажу я об этом способе на примере товарного чека. Испробовать его может любой человек, для этого надо взять этот и этот файл и кинуть их по адресу www.ваш сайт.ru/bitrix/admin/reports/.
Также необходимо подключить соответствующую php библиотеку для работы с файламы excel. В данном случае мы используем PHPExcel. Вам нужно кинуть все из папки Classes (которая находится в данном архиве) сюда www.ваш сайт.ru/bitrix/php_interface/include/. Важно: библиотека PHPExcel не работает если настройка PHP mbstring.func_overload = 2 (должно быть 0)
Тогда при печати заказа в административном разделе вашего сайта появится такая графа:

Товарный чек в формате xml Битрикс

Вы можете использовать скачанные файлы у себя, для этого просто подставьте ваши реквизиты в файле tovar_chek.xls.
Ниже я приведу исходный код файла для формирования товарного чека (tovar_chek.php):

<?if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();
// <title>Товарный чек (Excel)</title>
function c($text) {return $text;}
if (!function_exists("d")) {
	function d($text) {echo '<pre>'.print_r($text).'</pre>';}
}

/*d($arOrder);
d($arOrderProps);
exit();*/

CModule::IncludeModule("iblock");
$cartItems = array();
$iblockItems = array();
$rs = CSaleBasket::GetList(array(), array('ORDER_ID'=>$ORDER_ID));
while ($ar = $rs->GetNext()) {
	$ids[] = $ar['PRODUCT_ID'];
	$cartItems[] = $ar;
}
// замены
$filename = "tovar_chek.xls";
$find = array(
	"#ORDER_NUMBER#",
	"#CURRENT_DATE#",
	"#ORDER_DATE#",
	"#TOTAL_PRICE#",
	"#TOTAL_PRICE_TEXT#",
	"#COMPANY_NAME#",
	"#DELIVERY_ZIP#",
	"#DELIVERY_CITY#",
	"#DELIVERY_ADDRESS#",
	"#DELIVERY_CONTACT_PERSON#",
	"#DELIVERY_CONTACT_TEL#",
	"#TOTAL_WEIGHT#",
	"#TOTAL_QUANTITY#",
	"#ORDER_NUMBER_DATA#",
	"#POLUCHENO#",
);

function utf_ucfirst($string) {
            $string_array = explode(' ', $string, 2);
            $string_array['0'] =  mb_convert_case($string_array['0'], MB_CASE_TITLE, "UTF-8");
            return $string_array['0']." ".$string_array['1'];
    }
$str = Number2Word_Rus($arOrder['PRICE'], "Y");

$replace = array(
	$ORDER_ID,
	date("d.m.Y"),
	$arOrder['DATE_INSERT_FORMAT'],
	$arOrder['PRICE'],
	utf_ucfirst($str),
	$arOrderProps['orgname']?$arOrderProps['orgname']:$arOrderProps['contact_person'],
	$arOrderProps['zip'],
	$arOrderProps['city'],
	$arOrderProps['address'],
	$arOrderProps['contact_person'],
	$arOrderProps['phone'],
	$total_weight,
	count($cartItems)+($arOrder['PRICE_DELIVERY']>0?1:0),
	"Товарный чек № ".$ORDER_ID." от ".date("d.m.Y"),
	"Получено: ".$arOrder['PRICE']." руб.",
);
$replace = array_map("c", $replace);
$rs = CIBlockElement::GetList(array(), array('ID'=>$ids));
while ($el = $rs->GetNext()) {
	$el['PROPERTIES'] = array();
	$rsProp = CIBlockElement::GetProperty($el['IBLOCK_ID'], $el['ID']);
	while ($arProp = $rsProp->GetNext()) {
		$el['PROPERTIES'][$arProp['CODE']] = $arProp;
	}
	$iblockItems[$el['ID']] = $el;
}
require_once($_SERVER['DOCUMENT_ROOT']."/bitrix/php_interface/include/PHPExcel.php");

$objPHPExcel = PHPExcel_IOFactory::load($_SERVER['DOCUMENT_ROOT']."/bitrix/admin/reports/".$filename);

// Замена ячеек
foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) {
	//$worksheet->setTitle("Название");
	//d(get_class_methods($worksheet)); exit();
	//$worksheet->insertNewRowBefore($existing_row_items, count($cartItems));
	//$worksheet->removeRow();
	foreach ($worksheet->getRowIterator() as $row) {
		$cellIterator = $row->getCellIterator();
		//$cellIterator->setIterateOnlyExistingCells(false); // Loop all cells, even if it is not set
		foreach ($cellIterator as $cell) {
			if (!is_null($cell)) {
				$value = $cell->getCalculatedValue();
				if ($value=="#ITEM_INSTANCE_NUMBER#") { // нашли строку для товаров
					$row_index = $row->getRowIndex();
					$base_row = $row; // сначала возьмем первую строку как образец
					$new_rows_count = count($cartItems);
					if ($arOrder['PRICE_DELIVERY']>0) $new_rows_count++;
					$worksheet->insertNewRowBefore($row_index+1, $new_rows_count);
					$worksheet->removeRow($row_index, 1);
					$counter = 1;
					foreach ($cartItems as $cartItem) {
						$row_edit = $row_index+$counter-1;
                                             if ($counter > 1)
                                               {
                                                $worksheet->mergeCells('B'.$row_edit.':C'.$row_edit);
                                                $worksheet->mergeCells('D'.$row_edit.':T'.$row_edit);
                                                $worksheet->mergeCells('U'.$row_edit.':W'.$row_edit);
                                                $worksheet->mergeCells('X'.$row_edit.':Y'.$row_edit);
                                                $worksheet->mergeCells('Z'.$row_edit.':AC'.$row_edit);
                                                $worksheet->mergeCells('AD'.$row_edit.':AG'.$row_edit);
                                               }
						$worksheet->setCellValue('B'.$row_edit, $counter); // порядковый номер
						$worksheet->setCellValue('D'.$row_edit, c($cartItem['NAME'])); // название
						$worksheet->setCellValue('X'.$row_edit, "шт"); // единица измерения
						$worksheet->setCellValue('U'.$row_edit, $cartItem['QUANTITY']); // количество
						$worksheet->setCellValue('Z'.$row_edit, $cartItem['PRICE']); // количество
						$worksheet->setCellValue('AD'.$row_edit, $cartItem['PRICE']*$cartItem['QUANTITY']); // количество
						$counter++;
					}
					if ($arOrder['PRICE_DELIVERY']>0) {
						$row_edit++;
                                                $worksheet->mergeCells('B'.$row_edit.':C'.$row_edit);
                                                $worksheet->mergeCells('D'.$row_edit.':T'.$row_edit);
                                                $worksheet->mergeCells('U'.$row_edit.':W'.$row_edit);
                                                $worksheet->mergeCells('X'.$row_edit.':Y'.$row_edit);
                                                $worksheet->mergeCells('Z'.$row_edit.':AC'.$row_edit);
                                                $worksheet->mergeCells('AD'.$row_edit.':AG'.$row_edit);
						$worksheet->setCellValue('B'.$row_edit, $counter); // порядковый номер
						$worksheet->setCellValue('D'.$row_edit, c("Доставка")); // название
						$worksheet->setCellValue('X'.$row_edit, ""); // единица измерения
						$worksheet->setCellValue('U'.$row_edit, "1"); // количество
						$worksheet->setCellValue('Z'.$row_edit, $arOrder['PRICE_DELIVERY']); // количество
						$worksheet->setCellValue('AD'.$row_edit, $arOrder['PRICE_DELIVERY']); // количество
					}

						$row_edit++;
						$row_edit++;
						$row_edit++;
						$row_edit++;
						$row_edit++;
                                                $worksheet->mergeCells('B'.$row_edit.':E'.$row_edit);
                                                $worksheet->mergeCells('F'.$row_edit.':P'.$row_edit);
						$worksheet->setCellValue('B'.$row_edit, c("Продавец: "));
						$worksheet->setCellValue('F'.$row_edit, "______________________________________");

						$row_edit++;
						$row_edit++;
                                                $worksheet->mergeCells('B'.$row_edit.':AG'.$row_edit);
						$worksheet->setCellValue('B'.$row_edit, "________________________________________________________________________________________________________________");

				} else {
					if (strpos($value, "#")!==false) {
						$cell->setValue(str_replace($find, $replace, $value));
					}
				}
			}
		}
	}
}

$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
$objWriter->save("replaced_".$filename);

$data = file_get_contents("replaced_".$filename);

header('Pragma: public');
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");                  // Date in the past
header('Last-Modified: '.gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');     // HTTP/1.1
header('Cache-Control: pre-check=0, post-check=0, max-age=0');    // HTTP/1.1
header("Pragma: no-cache");
header("Expires: 0");
header('Content-Transfer-Encoding: none');
header('Content-Type: application/vnd.ms-excel;');                 // This should work for IE & Opera
header("Content-type: application/x-msexcel");                    // This should work for the rest
header('Content-Disposition: attachment; filename="Товарный чек для заказа №'.$ORDER_ID.'".xls');
echo $data;
?>
Похожие посты:
  • Выгрузка заказов в xml файл для курьерской службы
  • Отправка письма на почту пользователю при оформлении нового заказа (Битрикс)
  • Создать аккаунт администратора на Битриксе
  • Автозаполнение символьного кода у товаров. Функция – агент для Битрикса.
  • Напоминание пользователю о появлении товара (Битрикс)
  • 9 комментариев: Товарный чек в формате xml (Excel)

    1. Ни в какую не хочет работать. сохраняет файл а при открытии Ексель пишет что формат не тот и выдет какойто бред. Пробывал и на сайте с UTF-8 и с CP1251 одно и тоже.
      Пробывал закоментировать весь foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) {…} (// Замена ячеек) – тоже самое.
      Таже пробывал играть с «Excel5″ – менял на другие значения.

      • Лаврушин Алексей

        Файлы использовали мои? Пример 100% рабочий, взят с действующего интернет магазина. Попробуйте киньте мне файл, генерируемый вашим кодом, и исходные, но ничего не обещаю)

    2. Проблема решилась. Косяк был в том что сохранялся файл нормально но вот после
      его открытия $data = file_get_contents(«replaced_».$filename); вылезала какая-то ерунда (возможно особенности хостинга).
      Нашел решение тут http://phpexcel.codeplex.com/discussions/250120
      Лучше и правильнее сделать вывод через $objWriter->save(‘php://output’);
      Спасибо за статью, нашел кучу интересного в Вашем блоге.

    3. Fatal error: Class ‘PHPExcel_IOFactory’ not found in C:\Program Files\Bitrix Environment\www\bitrix\admin\reports\tovar_chek.php on line 76
      Что я ге так делаю??

    4. Владимир

      Тебе же все сказано в ошибке: Класс PHPExcel_IOFactory не найден на 76 строке, пути смотри когда инклудишь

    5. статья действительно отличная, воспользовался, если бы нашел раньше. тем не менее уже написал свой подобный скрипт. библиотека действительно предоставляет широкие возможности…
      остался один маленький нерешенный вопрос – не могу найти информации, как через PHPExcel задать стиль отдельному слову в ячейке(не ВСЕЙ ячейке)? возможно ли это? я понимаю, возникает вопрос «зачем?», если можно разместить в разных ячейках… тем не менее, формат моего документа предполагает подобное извращение.

    6. Ярослав

      Спасибо, решение отличное!
      Только не могу разобраться, как добавить туда другие значения, например ФИО заказчика, его адрес и телефон.
      Подскажите пожалуйста. Заранее благодарен!

    7. Отлична стать, спасибо:) Однако есть вопрос: мне нужно немного сменить архитектуру чека и добавить кое какие данные, не могли бы Вы подсказать где искать перечень переменных окружения типа #ITEM_NAME#, мне нужен тип доставки, например? Спасибо и за ответ:)

    8. А есть готовый вариант счета фактуры?

    Добавить комментарий:

    Подтвердите, что Вы не бот — выберите человечка с поднятой рукой: