Показать сообщение отдельно
Старый 19.09.2006, 17:35   #1  
AlexeyS is offline
AlexeyS
Участник
 
404 / 339 (12) ++++++
Регистрация: 15.06.2004
Адрес: москва
Экспорт в эксель через XML, еще один вариант
была задача - сделать вывод в эксель счета, накладной и сч.-фактуры,
так как некоторые клиенты хотят именно так и никак иначе

сначала пробовал сделать некое универсальное решение через форму стандартной печати,
но мне это оказалось не по зубам ))
к тому-же обязательное требование - сохранить форматирование отчета (чтобы было как в 1С)

Excel 2003 нормально понимает XML
поэтому сделал такой вариант - в отчете перегружается метод print
формирую XML с помощью XMLDocument,

Код:
xmlDoc = new XMLDocument();
xmlDoc.loadXML('<?xml version="1.0" encoding="windows-1251"?><?xml-stylesheet type="text/xsl" href="smpl05.xsl"?><Bill/>');
в итоге получаю что-то вроде

Код:
<CustVendFacture>
	<Header>
		<getFactureId>012345</getFactureId>
		<FactureDate>01/09/2006</FactureDate>
		<getCompanyName>ПРОДАВЕЦ</getCompanyName>
		<getCompanyAddress>АДРЕС ПРОДАВЦА</getCompanyAddress>
		<getINNOfCompany>ИНН ПРОДАВЦА</getINNOfCompany>
		<getKPPUOfCompany>КПП ПРОДАВЦА</getKPPUOfCompany>
	</Header>
	<Body>
		<Line>
			<ItemName>ТОВАР1</ItemName>
			<getUnitIdTxt>шт</getUnitIdTxt>
			<getQty>2400</getQty>
			<getPrice>570</getPrice>
		</Line>
		<Line>
		...
		</Line>
	</Body>
</CustVendFacture>
который преобразую с помощью XSL,
XSL делаю так - подготавливаю шаблон, в нужных позициях подставляя имена переменных,
например название компании - getCompanyName, сохраняю из Excel-я в XML,
в файле заменяю заголовок

Код:
<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:o="urn:schemas-microsoft-com:office:office"
 xmlns:x="urn:schemas-microsoft-com:office:excel"
 xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:html="http://www.w3.org/TR/REC-html40">
на

Код:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns="urn:schemas-microsoft-com:office:spreadsheet"
  xmlns:o="urn:schemas-microsoft-com:office:office" 
  xmlns:x="urn:schemas-microsoft-com:office:excel"
  xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
  <xsl:template match="/">
    <xsl:processing-instruction name="mso-application">
      <xsl:text>progid="Excel.Sheet"</xsl:text>
    </xsl:processing-instruction>
<Workbook>
в полученном файле заменяю getCompanyName
на
Код:
<xsl:value-of select="CustVendFacture/Header/getCompanyName"/>
для строк накладной добавляю цикл

Код:
   <xsl:for-each select="CustVendFacture/Body/Line">
   <Row ss:AutoFitHeight="0">
    <Cell ss:Index="2" ss:StyleID="s38"><Data ss:Type="String"><xsl:value-of select="ItemName"/></Data></Cell>
    <Cell ss:StyleID="s39"><Data ss:Type="String"><xsl:value-of select="getUnitIdTxt"/></Data></Cell>
    <Cell ss:StyleID="s40"><Data ss:Type="Number"><xsl:value-of select="getQty"/></Data></Cell>
    <Cell ss:StyleID="s40"><Data ss:Type="Number"><xsl:value-of select="getPrice"/></Data></Cell>
    ...
   </Row>
   </xsl:for-each>
в конце добавляю

Код:
</xsl:template>
</xsl:stylesheet>
также находим
Код:
<Table ss:ExpandedColumnCount="256" ss:ExpandedRowCount="
в ExpandedRowCount ставим 256 или больше. это количество строк,
если его будет слишком мало - Excel будет грязно ругаться
на несоответствие указанному и реальному количеству строк в файле

также выводимые числа должны быть определенного вида,
например num2Str(Price, 3, 2, 1, 0), то есть без пробелов и разделитель - точка

полученый XML передаю в ActiveX Spreadsheet, положенный на форму.
после этого нажимаем на кнопку экспорта и готово
с принципе, думаю можно сразу передавать во внешний Excel через COM

плюсы: работает быстро, формирует по шаблону готовый Excel-отчет
минусы: почему-то не сохраняет форматирование (перенос слов в ячейке),
потом нужно вручную менять формат ячейки
За это сообщение автора поблагодарили: mazzy (5), alex55 (3).