Wednesday, November 18, 2009

PHP-EXCEL-XML

Reporting dalam Excel form? Kenapa tidak. Saya secara pribadi
udah ngalamin, hasil print out browser yg berantakan,
tidak sama antara 1 sama lain dimana dasar codingnya sama, dsb.
Nah... sempat terpikir gunakan FPDF aja atau TCPDF.
Alhasil, mungkin saya nya yg kurang bisa,
seharian berkutat dan memble juga.
Pada akhir nya saya melirik teknik XML-spreadsheet.
Dimana teknik nya mencakup:

1. XML-spreadsheet.
2. Force Download.

Oke, kita bedah satu-satu. XML, humm...
sounds familiar?
Saya akan coba mengenalkan apa itu XML,
melalui link-link ini:
1. w3school
2. tizag
3. ibm developerworks
Bagi pemula jangan melewati bagian ini, untuk
yg expert ada bagus nya utk mengunjungi link-link tsb
utk sekedar review.

Setelah anda mengunjungi link-link tsb,
buat file excel baru lalu di row 1 anda buat header.
Misalkan: col1 => Nama, col2 => Nim, col3=> Nilai.
Setelah itu row 2 anda masukan data,
sesuai dgn kolom. Misalkan: col1 => Adesanto,
col2 => 0911090001, col3=> 99 (tidak 100, krn manusia
tak ada yg sempurna).
Lalu File->"Save As"->XML-spreadsheet, beri nama
"my-xml-spreadsheet.xml".

Langkah berikut nya adalah menggunakan editor favorit anda,
untuk membuka "my-xml-spreadsheet.xml".
Saya menganjurkan Notepad++ windows, atau gedit linux,
untuk editor pilihan/rujukan dari saya.
Scroll down hingga anda menemukan tag
<Worksheet ss:Name="Sheet1"> <table ...>.
Perhatian, ss:Name="Sheet1" adalah nama worksheet default
excel/calc, akan tidak sama jika sebelumnya telah me-rename.
Dan interesting part nya, terletak di tag <table ...>.
Buang informasi tambahan dalam table utk mencegah
tidak konsistennya data, sehingga menjadi <table>,
setelah itu di-Save.

Kita akan membagi "my-xml-spreadsheet.xml" menjadi 3 bagian,
$excelHeader, $excelBody dan $excelFooter.
Lalu masih dari "my-xml-spreadsheet.xml",
copy paste dari awal data hingga akhir tag </Row> ke 1,
untuk menjadi data utk $excelHeader.
Dan copy paste dari tag </table> hingga paling akhir
menjadi data $excelFooter.
Data XML:
<?xml version="1.0"?>
<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">
<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
<Author>Adesanto Asman</Author>
<LastAuthor>Adesanto Asman</LastAuthor>
<Created>2009-11-18T13:37:59Z</Created>
<Company>DIGIKREASI INOVASINDO</Company>
<Version>10.2625</Version>
</DocumentProperties>
<OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">
<DownloadComponents/>
<LocationOfComponents HRef="file:///F:\"/>
</OfficeDocumentSettings>
<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
<WindowHeight>7935</WindowHeight>
<WindowWidth>19035</WindowWidth>
<WindowTopX>0</WindowTopX>
<WindowTopY>120</WindowTopY>
<ProtectStructure>False</ProtectStructure>
<ProtectWindows>False</ProtectWindows>
</ExcelWorkbook>
<Styles>
<Style ss:ID="Default" ss:Name="Normal">
<Alignment ss:Vertical="Bottom"/>
<Borders/>
<Font/>
<Interior/>
<NumberFormat/>
<Protection/>
</Style>
<Style ss:ID="s23">
<Alignment ss:Horizontal="Center" ss:Vertical="Bottom"/>
<Borders>
<Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="2"/>
<Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="2"/>
<Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="2"/>
<Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="2"/>
</Borders>
<Font x:Family="Swiss" ss:Bold="1"/>
</Style>
</Styles>
<Worksheet ss:Name="Sheet1">
<Table>
<Column ss:Width="46.5"/>
<Column ss:Width="52.5"/>
<Row ss:Height="13.5">
<Cell ss:StyleID="s23"><Data ss:Type="String">Nama</Data></Cell>
<Cell ss:StyleID="s23"><Data ss:Type="String">NIM</Data></Cell>
<Cell ss:StyleID="s23"><Data ss:Type="String">Nilai</Data></Cell>
</Row>
<Row>
<Cell><Data ss:Type="String">Adesanto</Data></Cell>
<Cell><Data ss:Type="Number">911090001</Data></Cell>
<Cell><Data ss:Type="Number">99</Data></Cell>
</Row>
</Table>
</Worksheet>
</Workbook>

$excelHeader = '<?xml version="1.0"?>
<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">
<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
<Author>Adesanto Asman</Author>
<LastAuthor>Adesanto Asman</LastAuthor>
<Created>2009-11-18T13:37:59Z</Created>
<Company>DIGIKREASI INOVASINDO</Company>
<Version>10.2625</Version>
</DocumentProperties>
<OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">
<DownloadComponents/>
<LocationOfComponents HRef="file:///F:\"/>
</OfficeDocumentSettings>
<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
<WindowHeight>7935</WindowHeight>
<WindowWidth>19035</WindowWidth>
<WindowTopX>0</WindowTopX>
<WindowTopY>120</WindowTopY>
<ProtectStructure>False</ProtectStructure>
<ProtectWindows>False</ProtectWindows>
</ExcelWorkbook>
<Styles>
<Style ss:ID="Default" ss:Name="Normal">
<Alignment ss:Vertical="Bottom"/>
<Borders/>
<Font/>
<Interior/>
<NumberFormat/>
<Protection/>
</Style>
<Style ss:ID="s23">
<Alignment ss:Horizontal="Center" ss:Vertical="Bottom"/>
<Borders>
<Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="2"/>
<Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="2"/>
<Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="2"/>
<Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="2"/>
</Borders>
<Font x:Family="Swiss" ss:Bold="1"/>
</Style>
</Styles>
<Worksheet ss:Name="Sheet1">
<Table>
<Column ss:Width="46.5"/>
<Column ss:Width="52.5"/>
<Row ss:Height="13.5">
<Cell ss:StyleID="s23"><Data ss:Type="String">Nama</Data></Cell>
<Cell ss:StyleID="s23"><Data ss:Type="String">NIM</Data></Cell>
<Cell ss:StyleID="s23"><Data ss:Type="String">Nilai</Data></Cell>
</Row>';

$excelFooter = '</Table>
</Worksheet>
</Workbook>';

Data yg akan kita tampilkan/sisipkan,
akan kita assign ke $excelBody.
Caranya copy paste dari tag <Row>
hingga </Row> ke 2, ke dalam coding kita.

...
for($iRow = 0; $iRow < 10; $iRow++){

$excelBody = "<Row>
<Cell><Data ss:Type=\"String\">Adesanto</Data></Cell>
<Cell><Data ss:Type=\"Number\">911090001</Data></Cell>
<Cell><Data ss:Type=\"Number\">".$iRow."</Data></Cell>
</Row>";
}
...

Ok kita sudah selesai dg file XML kita.
Sekarang user harus diberi kemudahan, utk dapat melihat
hasil dlm bentuk excel format. Cukup taruh
code ini diawal:

$archiveName = 'php-excel-xml.xml';
$length = 2000000; // utk kelengkapan code force download, saya beri value statis
$contentType = "text/plain";
$option = 'inline';

header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
header("Content-Type: application/".$contentType."");
header("Content-Disposition: ".$option."; filename=".basename($archiveName).";" );
header("Content-Transfer-Encoding: binary;");
header("Content-Length: ".$length);

Disambung dengan

echo $excelHeader.
$excelBody.
$excelFooter;

Seharus nya setelah code di execute di browser,
akan muncul pop-up download,
pilih open with: excel, atau, scalc (open office excel).

Sebagai catatan, ketika kita membentuk $excelBody
pastikan utk meng-"escape" karakter ini, '&' dan '"'.
Khusus karakter tanda kutip 1, ada perlakuan khusus yaitu,
<Data ss:Type="String" x:Ticked="1"></Data>

Happy Coding.

No comments: