Hallo! Selamat Datang di Marketplace produk digital, Freelancer terbaik di indonesia (67507 Members, 783 Products, 5291 Topic, 12956 Comments)

Cara Import data dari Excel ke Database Mysql dengan Php

Dibuat
Login Terakhir 5 Bulan lalu,
Telah Dilihat 4361 Kali
Ahmad fatony budiman Mengatakan : Sultan Account
  1. Assalamu'alaikum,
  2.  
  3. Dear All,
  4. ane udah pakai script berikut ini untuk import data ribuan data, tapi data yang masuk ke database mysql ada yang gagal import jumlahnya antara 2-10 an
  5.  
  6. Berikut scriptnya
  7.  
  8. <?php
  9. // menggunakan class phpExcelReader
  10. include "Classes/excel_reader2.php";
  11.  
  12. // koneksi ke mysql
  13.  
  14. // membaca file excel yang diupload
  15. $data = new Spreadsheet_Excel_Reader($_FILES['userfile']['tmp_name']);
  16.  
  17. // membaca jumlah baris dari data excel
  18. $baris = $data->rowcount($sheet_index=0);
  19.  
  20. // nilai awal counter untuk jumlah data yang sukses dan yang gagal diimport
  21. $sukses = 0;
  22. $gagal = 0;
  23.  
  24. // import data excel mulai baris ke-2 (karena baris pertama adalah nama kolom)
  25. for ($i=2; $i<=$baris; $i++)
  26. {
  27. // membaca data storekey (kolom ke-1)
  28. $nama = $data->val($i, 1);
  29. $telepon = $data->val($i, 2);
  30. $creation_date = $data->val($i, 3);
  31.  
  32.  
  33. // setelah data dibaca, sisipkan ke dalam tabel
  34. $query = "INSERT INTO master
  35. VALUES (
  36. '$nama',
  37. '$telepon',
  38. '$creation_date'
  39.  
  40. )";
  41.  
  42. $hasil = mysql_query($query);
  43.  
  44. // jika proses insert data sukses, maka counter $sukses bertambah
  45. // jika gagal, maka counter $gagal yang bertambah
  46. if ($hasil) $sukses++;
  47. else $gagal++;
  48. }
  49.  
  50. // tampilan status sukses dan gagal
  51. echo "<h3>Proses import data selesai.</h3>";
  52. echo "<p>Jumlah data yang sukses diimport : ".$sukses."<br>";
  53. echo "Jumlah data yang gagal diimport : ".$gagal."</p>";
  54.  
  55. ?>
  56.  
  57.  
  58. <section class="content">
  59. <div class="row">
  60. <div class="box box-default">
  61. <div class="box box-info">
  62. <h4 class="box-title">Upload File Master </h4>
  63. <table width="435" border="0" cellspacing="0" class="table">
  64.  
  65. <form method="post" enctype="multipart/form-data" action="?module=upload">
  66. <div class="col-sm-3">
  67. <div class="form-group">
  68.  
  69. Silakan Pilih File Excel: <input name="userfile" type="file">
  70. <input name="upload" type="submit" value="Submit">
  71. </div></div>
  72. </tr>
  73. </table>
  74. </form>
  75. </section>
  76. </div>
  77. </div>
  78. </div>
  79.  
  80.  
  81. kenapa ya penyebabnya ?? makasih all
  82.  

Ada 4 Jawaban

Ahmad fatony budiman
commented on 15 Mei 2017 17:29:48
  1. solved, ternyata penyebabnya ada tanda ' di file excelnya.
PHPMU.COM Support
commented on 15 Mei 2017 21:14:23
  1. oke mas, alhamdulillah,.. :)
  2. sebaiknya untuk pertanyaan seperti ini sekalian share table database
  3. dan file terkait seperti excel_reader2.php agar teman2 bisa coba2kan juga disini mas,..
Ahmad fatony budiman
commented on 17 Mei 2017 11:13:22
  1. excel_reader2.php
  2.  
  3. <?php
  4. /**
  5.  * A class for reading Microsoft Excel (97/2003) Spreadsheets.
  6.  *
  7.  * Version 2.21
  8.  *
  9.  * Enhanced and maintained by Matt Kruse < http://mattkruse.com >
  10.  * Maintained at http://code.google.com/p/php-excel-reader/
  11.  *
  12.  * Format parsing and MUCH more contributed by:
  13.  * Matt Roxburgh < http://www.roxburgh.me.uk >
  14.  *
  15.  * DOCUMENTATION
  16.  * =============
  17.  * http://code.google.com/p/php-excel-reader/wiki/Documentation
  18.  *
  19.  * CHANGE LOG
  20.  * ==========
  21.  * http://code.google.com/p/php-excel-reader/wiki/ChangeHistory
  22.  *
  23.  * DISCUSSION/SUPPORT
  24.  * ==================
  25.  * http://groups.google.com/group/php-excel-reader-discuss/topics
  26.  *
  27.  * --------------------------------------------------------------------------
  28.  *
  29.  * Originally developed by Vadim Tkachenko under the name PHPExcelReader.
  30.  * (http://sourceforge.net/projects/phpexcelreader)
  31.  * Based on the Java version by Andy Khan (http://www.andykhan.com). Now
  32.  * maintained by David Sanders. Reads only Biff 7 and Biff 8 formats.
  33.  *
  34.  * PHP versions 4 and 5
  35.  *
  36.  * LICENSE: This source file is subject to version 3.0 of the PHP license
  37.  * that is available through the world-wide-web at the following URI:
  38.  * http://www.php.net/license/3_0.txt. If you did not receive a copy of
  39.  * the PHP License and are unable to obtain it through the web, please
  40.  * send a note to license@php.net so we can mail you a copy immediately.
  41.  *
  42.  * @category Spreadsheet
  43.  * @package Spreadsheet_Excel_Reader
  44.  * @author Vadim Tkachenko <vt@apachephp.com>
  45.  * @license http://www.php.net/license/3_0.txt PHP License 3.0
  46.  * @version CVS: $Id: reader.php 19 2007-03-13 12:42:41Z shangxiao $
  47.  * @link http://pear.php.net/package/Spreadsheet_Excel_Reader
  48.  * @see OLE, Spreadsheet_Excel_Writer
  49.  * --------------------------------------------------------------------------
  50.  */
  51.  
  52. define('NUM_BIG_BLOCK_DEPOT_BLOCKS_POS', 0x2c);
  53. define('SMALL_BLOCK_DEPOT_BLOCK_POS', 0x3c);
  54. define('ROOT_START_BLOCK_POS', 0x30);
  55. define('BIG_BLOCK_SIZE', 0x200);
  56. define('SMALL_BLOCK_SIZE', 0x40);
  57. define('EXTENSION_BLOCK_POS', 0x44);
  58. define('NUM_EXTENSION_BLOCK_POS', 0x48);
  59. define('PROPERTY_STORAGE_BLOCK_SIZE', 0x80);
  60. define('BIG_BLOCK_DEPOT_BLOCKS_POS', 0x4c);
  61. define('SMALL_BLOCK_THRESHOLD', 0x1000);
  62. // property storage offsets
  63. define('SIZE_OF_NAME_POS', 0x40);
  64. define('TYPE_POS', 0x42);
  65. define('START_BLOCK_POS', 0x74);
  66. define('SIZE_POS', 0x78);
  67. define('IDENTIFIER_OLE', pack("CCCCCCCC",0xd0,0xcf,0x11,0xe0,0xa1,0xb1,0x1a,0xe1));
  68.  
  69.  
  70. function GetInt4d($data, $pos) {
  71. $value = ord($data[$pos]) | (ord($data[$pos+1]) << 8) | (ord($data[$pos+2]) << 16) | (ord($data[$pos+3]) << 24);
  72. if ($value>=4294967294) {
  73. $value=-2;
  74. }
  75. return $value;
  76. }
  77.  
  78. // http://uk.php.net/manual/en/function.getdate.php
  79. function gmgetdate($ts = null){
  80. $k = array('seconds','minutes','hours','mday','wday','mon','year','yday','weekday','month',0);
  81. return(array_comb($k,explode(":",gmdate('s:i:G:j:w:n:Y:z:l:F:U',is_null($ts)?time():$ts))));
  82. }
  83.  
  84. // Added for PHP4 compatibility
  85. function array_comb($array1, $array2) {
  86. $out = array();
  87. foreach ($array1 as $key => $value) {
  88. $out[$value] = $array2[$key];
  89. }
  90. return $out;
  91. }
  92.  
  93. function v($data,$pos) {
  94. return ord($data[$pos]) | ord($data[$pos+1])<<8;
  95. }
  96.  
  97. class OLERead {
  98. var $data = '';
  99. function OLERead(){ }
  100.  
  101. function read($sFileName){
  102. // check if file exist and is readable (Darko Miljanovic)
  103. if(!is_readable($sFileName)) {
  104. $this->error = 1;
  105. return false;
  106. }
  107. $this->data = @file_get_contents($sFileName);
  108. if (!$this->data) {
  109. $this->error = 1;
  110. return false;
  111. }
  112. if (substr($this->data, 0, 8) != IDENTIFIER_OLE) {
  113. $this->error = 1;
  114. return false;
  115. }
  116. $this->numBigBlockDepotBlocks = GetInt4d($this->data, NUM_BIG_BLOCK_DEPOT_BLOCKS_POS);
  117. $this->sbdStartBlock = GetInt4d($this->data, SMALL_BLOCK_DEPOT_BLOCK_POS);
  118. $this->rootStartBlock = GetInt4d($this->data, ROOT_START_BLOCK_POS);
  119. $this->extensionBlock = GetInt4d($this->data, EXTENSION_BLOCK_POS);
  120. $this->numExtensionBlocks = GetInt4d($this->data, NUM_EXTENSION_BLOCK_POS);
  121.  
  122. $bigBlockDepotBlocks = array();
  123. $pos = BIG_BLOCK_DEPOT_BLOCKS_POS;
  124. $bbdBlocks = $this->numBigBlockDepotBlocks;
  125. if ($this->numExtensionBlocks != 0) {
  126. $bbdBlocks = (BIG_BLOCK_SIZE - BIG_BLOCK_DEPOT_BLOCKS_POS)/4;
  127. }
  128.  
  129. for ($i = 0; $i < $bbdBlocks; $i++) {
  130. $bigBlockDepotBlocks[$i] = GetInt4d($this->data, $pos);
  131. $pos += 4;
  132. }
  133.  
  134.  
  135. for ($j = 0; $j < $this->numExtensionBlocks; $j++) {
  136. $pos = ($this->extensionBlock + 1) * BIG_BLOCK_SIZE;
  137. $blocksToRead = min($this->numBigBlockDepotBlocks - $bbdBlocks, BIG_BLOCK_SIZE / 4 - 1);
  138.  
  139. for ($i = $bbdBlocks; $i < $bbdBlocks + $blocksToRead; $i++) {
  140. $bigBlockDepotBlocks[$i] = GetInt4d($this->data, $pos);
  141. $pos += 4;
  142. }
  143.  
  144. $bbdBlocks += $blocksToRead;
  145. if ($bbdBlocks < $this->numBigBlockDepotBlocks) {
  146. $this->extensionBlock = GetInt4d($this->data, $pos);
  147. }
  148. }
  149.  
  150. // readBigBlockDepot
  151. $pos = 0;
  152. $index = 0;
  153. $this->bigBlockChain = array();
  154.  
  155. for ($i = 0; $i < $this->numBigBlockDepotBlocks; $i++) {
  156. $pos = ($bigBlockDepotBlocks[$i] + 1) * BIG_BLOCK_SIZE;
  157. //echo "pos = $pos";
  158. for ($j = 0 ; $j < BIG_BLOCK_SIZE / 4; $j++) {
  159. $this->bigBlockChain[$index] = GetInt4d($this->data, $pos);
  160. $pos += 4 ;
  161. $index++;
  162. }
  163. }
  164.  
  165. // readSmallBlockDepot();
  166. $pos = 0;
  167. $index = 0;
  168. $sbdBlock = $this->sbdStartBlock;
  169. $this->smallBlockChain = array();
  170.  
  171. while ($sbdBlock != -2) {
  172. $pos = ($sbdBlock + 1) * BIG_BLOCK_SIZE;
  173. for ($j = 0; $j < BIG_BLOCK_SIZE / 4; $j++) {
  174. $this->smallBlockChain[$index] = GetInt4d($this->data, $pos);
  175. $pos += 4;
  176. $index++;
  177. }
  178. $sbdBlock = $this->bigBlockChain[$sbdBlock];
  179. }
  180.  
  181.  
  182. // readData(rootStartBlock)
  183. $block = $this->rootStartBlock;
  184. $pos = 0;
  185. $this->entry = $this->__readData($block);
  186. $this->__readPropertySets();
  187. }
  188.  
  189. function __readData($bl) {
  190. $block = $bl;
  191. $pos = 0;
  192. $data = '';
  193. while ($block != -2) {
  194. $pos = ($block + 1) * BIG_BLOCK_SIZE;
  195. $data = $data.substr($this->data, $pos, BIG_BLOCK_SIZE);
  196. $block = $this->bigBlockChain[$block];
  197. }
  198. return $data;
  199. }
  200.  
  201. function __readPropertySets(){
  202. $offset = 0;
  203. while ($offset < strlen($this->entry)) {
  204. $d = substr($this->entry, $offset, PROPERTY_STORAGE_BLOCK_SIZE);
  205. $nameSize = ord($d[SIZE_OF_NAME_POS]) | (ord($d[SIZE_OF_NAME_POS+1]) << 8);
  206. $type = ord($d[TYPE_POS]);
  207. $startBlock = GetInt4d($d, START_BLOCK_POS);
  208. $size = GetInt4d($d, SIZE_POS);
  209. $name = '';
  210. for ($i = 0; $i < $nameSize ; $i++) {
  211. $name .= $d[$i];
  212. }
  213. $name = str_replace("\x00", "", $name);
  214. $this->props[] = array (
  215. 'name' => $name,
  216. 'type' => $type,
  217. 'startBlock' => $startBlock,
  218. 'size' => $size);
  219. if ((strtolower($name) == "workbook") || ( strtolower($name) == "book")) {
  220. $this->wrkbook = count($this->props) - 1;
  221. }
  222. if ($name == "Root Entry") {
  223. $this->rootentry = count($this->props) - 1;
  224. }
  225. $offset += PROPERTY_STORAGE_BLOCK_SIZE;
  226. }
  227.  
  228. }
  229.  
  230.  
  231. function getWorkBook(){
  232. if ($this->props[$this->wrkbook]['size'] < SMALL_BLOCK_THRESHOLD){
  233. $rootdata = $this->__readData($this->props[$this->rootentry]['startBlock']);
  234. $streamData = '';
  235. $block = $this->props[$this->wrkbook]['startBlock'];
  236. $pos = 0;
  237. while ($block != -2) {
  238. $pos = $block * SMALL_BLOCK_SIZE;
  239. $streamData .= substr($rootdata, $pos, SMALL_BLOCK_SIZE);
  240. $block = $this->smallBlockChain[$block];
  241. }
  242. return $streamData;
  243. }else{
  244. $numBlocks = $this->props[$this->wrkbook]['size'] / BIG_BLOCK_SIZE;
  245. if ($this->props[$this->wrkbook]['size'] % BIG_BLOCK_SIZE != 0) {
  246. $numBlocks++;
  247. }
  248.  
  249. if ($numBlocks == 0) return '';
  250. $streamData = '';
  251. $block = $this->props[$this->wrkbook]['startBlock'];
  252. $pos = 0;
  253. while ($block != -2) {
  254. $pos = ($block + 1) * BIG_BLOCK_SIZE;
  255. $streamData .= substr($this->data, $pos, BIG_BLOCK_SIZE);
  256. $block = $this->bigBlockChain[$block];
  257. }
  258. return $streamData;
  259. }
  260. }
  261.  
  262. }
  263.  
  264. define('SPREADSHEET_EXCEL_READER_BIFF8', 0x600);
  265. define('SPREADSHEET_EXCEL_READER_BIFF7', 0x500);
  266. define('SPREADSHEET_EXCEL_READER_WORKBOOKGLOBALS', 0x5);
  267. define('SPREADSHEET_EXCEL_READER_WORKSHEET', 0x10);
  268. define('SPREADSHEET_EXCEL_READER_TYPE_BOF', 0x809);
  269. define('SPREADSHEET_EXCEL_READER_TYPE_EOF', 0x0a);
  270. define('SPREADSHEET_EXCEL_READER_TYPE_BOUNDSHEET', 0x85);
  271. define('SPREADSHEET_EXCEL_READER_TYPE_DIMENSION', 0x200);
  272. define('SPREADSHEET_EXCEL_READER_TYPE_ROW', 0x208);
  273. define('SPREADSHEET_EXCEL_READER_TYPE_DBCELL', 0xd7);
  274. define('SPREADSHEET_EXCEL_READER_TYPE_FILEPASS', 0x2f);
  275. define('SPREADSHEET_EXCEL_READER_TYPE_NOTE', 0x1c);
  276. define('SPREADSHEET_EXCEL_READER_TYPE_TXO', 0x1b6);
  277. define('SPREADSHEET_EXCEL_READER_TYPE_RK', 0x7e);
  278. define('SPREADSHEET_EXCEL_READER_TYPE_RK2', 0x27e);
  279. define('SPREADSHEET_EXCEL_READER_TYPE_MULRK', 0xbd);
  280. define('SPREADSHEET_EXCEL_READER_TYPE_MULBLANK', 0xbe);
  281. define('SPREADSHEET_EXCEL_READER_TYPE_INDEX', 0x20b);
  282. define('SPREADSHEET_EXCEL_READER_TYPE_SST', 0xfc);
  283. define('SPREADSHEET_EXCEL_READER_TYPE_EXTSST', 0xff);
  284. define('SPREADSHEET_EXCEL_READER_TYPE_CONTINUE', 0x3c);
  285. define('SPREADSHEET_EXCEL_READER_TYPE_LABEL', 0x204);
  286. define('SPREADSHEET_EXCEL_READER_TYPE_LABELSST', 0xfd);
  287. define('SPREADSHEET_EXCEL_READER_TYPE_NUMBER', 0x203);
  288. define('SPREADSHEET_EXCEL_READER_TYPE_NAME', 0x18);
  289. define('SPREADSHEET_EXCEL_READER_TYPE_ARRAY', 0x221);
  290. define('SPREADSHEET_EXCEL_READER_TYPE_STRING', 0x207);
  291. define('SPREADSHEET_EXCEL_READER_TYPE_FORMULA', 0x406);
  292. define('SPREADSHEET_EXCEL_READER_TYPE_FORMULA2', 0x6);
  293. define('SPREADSHEET_EXCEL_READER_TYPE_FORMAT', 0x41e);
  294. define('SPREADSHEET_EXCEL_READER_TYPE_XF', 0xe0);
  295. define('SPREADSHEET_EXCEL_READER_TYPE_BOOLERR', 0x205);
  296. define('SPREADSHEET_EXCEL_READER_TYPE_FONT', 0x0031);
  297. define('SPREADSHEET_EXCEL_READER_TYPE_PALETTE', 0x0092);
  298. define('SPREADSHEET_EXCEL_READER_TYPE_UNKNOWN', 0xffff);
  299. define('SPREADSHEET_EXCEL_READER_TYPE_NINETEENFOUR', 0x22);
  300. define('SPREADSHEET_EXCEL_READER_TYPE_MERGEDCELLS', 0xE5);
  301. define('SPREADSHEET_EXCEL_READER_UTCOFFSETDAYS' , 25569);
  302. define('SPREADSHEET_EXCEL_READER_UTCOFFSETDAYS1904', 24107);
  303. define('SPREADSHEET_EXCEL_READER_MSINADAY', 86400);
  304. define('SPREADSHEET_EXCEL_READER_TYPE_HYPER', 0x01b8);
  305. define('SPREADSHEET_EXCEL_READER_TYPE_COLINFO', 0x7d);
  306. define('SPREADSHEET_EXCEL_READER_TYPE_DEFCOLWIDTH', 0x55);
  307. define('SPREADSHEET_EXCEL_READER_TYPE_STANDARDWIDTH', 0x99);
  308. define('SPREADSHEET_EXCEL_READER_DEF_NUM_FORMAT', "%s");
  309.  
  310.  
  311. /*
  312. * Main Class
  313. */
  314. class Spreadsheet_Excel_Reader {
  315.  
  316. // MK: Added to make data retrieval easier
  317. var $colnames = array();
  318. var $colindexes = array();
  319. var $standardColWidth = 0;
  320. var $defaultColWidth = 0;
  321.  
  322. function myHex($d) {
  323. if ($d < 16) return "0" . dechex($d);
  324. return dechex($d);
  325. }
  326.  
  327. function dumpHexData($data, $pos, $length) {
  328. $info = "";
  329. for ($i = 0; $i <= $length; $i++) {
  330. $info .= ($i==0?"":" ") . $this->myHex(ord($data[$pos + $i])) . (ord($data[$pos + $i])>31? "[" . $data[$pos + $i] . "]":'');
  331. }
  332. return $info;
  333. }
  334.  
  335. function getCol($col) {
  336. if (is_string($col)) {
  337. $col = strtolower($col);
  338. if (array_key_exists($col,$this->colnames)) {
  339. $col = $this->colnames[$col];
  340. }
  341. }
  342. return $col;
  343. }
  344.  
  345. // PUBLIC API FUNCTIONS
  346. // --------------------
  347.  
  348. function val($row,$col,$sheet=0) {
  349. $col = $this->getCol($col);
  350. if (array_key_exists($row,$this->sheets[$sheet]['cells']) && array_key_exists($col,$this->sheets[$sheet]['cells'][$row])) {
  351. return $this->sheets[$sheet]['cells'][$row][$col];
  352. }
  353. return "";
  354. }
  355. function value($row,$col,$sheet=0) {
  356. return $this->val($row,$col,$sheet);
  357. }
  358. function info($row,$col,$type='',$sheet=0) {
  359. $col = $this->getCol($col);
  360. if (array_key_exists('cellsInfo',$this->sheets[$sheet])
  361. && array_key_exists($row,$this->sheets[$sheet]['cellsInfo'])
  362. && array_key_exists($col,$this->sheets[$sheet]['cellsInfo'][$row])
  363. && array_key_exists($type,$this->sheets[$sheet]['cellsInfo'][$row][$col])) {
  364. return $this->sheets[$sheet]['cellsInfo'][$row][$col][$type];
  365. }
  366. return "";
  367. }
  368. function type($row,$col,$sheet=0) {
  369. return $this->info($row,$col,'type',$sheet);
  370. }
  371. function raw($row,$col,$sheet=0) {
  372. return $this->info($row,$col,'raw',$sheet);
  373. }
  374. function rowspan($row,$col,$sheet=0) {
  375. $val = $this->info($row,$col,'rowspan',$sheet);
  376. if ($val=="") { return 1; }
  377. return $val;
  378. }
  379. function colspan($row,$col,$sheet=0) {
  380. $val = $this->info($row,$col,'colspan',$sheet);
  381. if ($val=="") { return 1; }
  382. return $val;
  383. }
  384. function hyperlink($row,$col,$sheet=0) {
  385. $link = $this->sheets[$sheet]['cellsInfo'][$row][$col]['hyperlink'];
  386. if ($link) {
  387. return $link['link'];
  388. }
  389. return '';
  390. }
  391. function rowcount($sheet=0) {
  392. return $this->sheets[$sheet]['numRows'];
  393. }
  394. function colcount($sheet=0) {
  395. return $this->sheets[$sheet]['numCols'];
  396. }
  397. function colwidth($col,$sheet=0) {
  398. // Col width is actually the width of the number 0. So we have to estimate and come close
  399. return $this->colInfo[$sheet][$col]['width']/9142*200;
  400. }
  401. function colhidden($col,$sheet=0) {
  402. return !!$this->colInfo[$sheet][$col]['hidden'];
  403. }
  404. function rowheight($row,$sheet=0) {
  405. return $this->rowInfo[$sheet][$row]['height'];
  406. }
  407. function rowhidden($row,$sheet=0) {
  408. return !!$this->rowInfo[$sheet][$row]['hidden'];
  409. }
  410.  
  411. // GET THE CSS FOR FORMATTING
  412. // ==========================
  413. function style($row,$col,$sheet=0,$properties='') {
  414. $css = "";
  415. $font=$this->font($row,$col,$sheet);
  416. if ($font!="") {
  417. $css .= "font-family:$font;";
  418. }
  419. $align=$this->align($row,$col,$sheet);
  420. if ($align!="") {
  421. $css .= "text-align:$align;";
  422. }
  423. $height=$this->height($row,$col,$sheet);
  424. if ($height!="") {
  425. $css .= "font-size:$height"."px;";
  426. }
  427. $bgcolor=$this->bgColor($row,$col,$sheet);
  428. if ($bgcolor!="") {
  429. $bgcolor = $this->colors[$bgcolor];
  430. $css .= "background-color:$bgcolor;";
  431. }
  432. $color=$this->color($row,$col,$sheet);
  433. if ($color!="") {
  434. $css .= "color:$color;";
  435. }
  436. $bold=$this->bold($row,$col,$sheet);
  437. if ($bold) {
  438. $css .= "font-weight:bold;";
  439. }
  440. $italic=$this->italic($row,$col,$sheet);
  441. if ($italic) {
  442. $css .= "font-style:italic;";
  443. }
  444. $underline=$this->underline($row,$col,$sheet);
  445. if ($underline) {
  446. $css .= "text-decoration:underline;";
  447. }
  448. // Borders
  449. $bLeft = $this->borderLeft($row,$col,$sheet);
  450. $bRight = $this->borderRight($row,$col,$sheet);
  451. $bTop = $this->borderTop($row,$col,$sheet);
  452. $bBottom = $this->borderBottom($row,$col,$sheet);
  453. $bLeftCol = $this->borderLeftColor($row,$col,$sheet);
  454. $bRightCol = $this->borderRightColor($row,$col,$sheet);
  455. $bTopCol = $this->borderTopColor($row,$col,$sheet);
  456. $bBottomCol = $this->borderBottomColor($row,$col,$sheet);
  457. // Try to output the minimal required style
  458. if ($bLeft!="" && $bLeft==$bRight && $bRight==$bTop && $bTop==$bBottom) {
  459. $css .= "border:" . $this->lineStylesCss[$bLeft] .";";
  460. }
  461. else {
  462. if ($bLeft!="") { $css .= "border-left:" . $this->lineStylesCss[$bLeft] .";"; }
  463. if ($bRight!="") { $css .= "border-right:" . $this->lineStylesCss[$bRight] .";"; }
  464. if ($bTop!="") { $css .= "border-top:" . $this->lineStylesCss[$bTop] .";"; }
  465. if ($bBottom!="") { $css .= "border-bottom:" . $this->lineStylesCss[$bBottom] .";"; }
  466. }
  467. // Only output border colors if there is an actual border specified
  468. if ($bLeft!="" && $bLeftCol!="") { $css .= "border-left-color:" . $bLeftCol .";"; }
  469. if ($bRight!="" && $bRightCol!="") { $css .= "border-right-color:" . $bRightCol .";"; }
  470. if ($bTop!="" && $bTopCol!="") { $css .= "border-top-color:" . $bTopCol . ";"; }
  471. if ($bBottom!="" && $bBottomCol!="") { $css .= "border-bottom-color:" . $bBottomCol .";"; }
  472.  
  473. return $css;
  474. }
  475.  
  476. // FORMAT PROPERTIES
  477. // =================
  478. function format($row,$col,$sheet=0) {
  479. return $this->info($row,$col,'format',$sheet);
  480. }
  481. function formatIndex($row,$col,$sheet=0) {
  482. return $this->info($row,$col,'formatIndex',$sheet);
  483. }
  484. function formatColor($row,$col,$sheet=0) {
  485. return $this->info($row,$col,'formatColor',$sheet);
  486. }
  487.  
  488. // CELL (XF) PROPERTIES
  489. // ====================
  490. function xfRecord($row,$col,$sheet=0) {
  491. $xfIndex = $this->info($row,$col,'xfIndex',$sheet);
  492. if ($xfIndex!="") {
  493. return $this->xfRecords[$xfIndex];
  494. }
  495. return null;
  496. }
  497. function xfProperty($row,$col,$sheet,$prop) {
  498. $xfRecord = $this->xfRecord($row,$col,$sheet);
  499. if ($xfRecord!=null) {
  500. return $xfRecord[$prop];
  501. }
  502. return "";
  503. }
  504. function align($row,$col,$sheet=0) {
  505. return $this->xfProperty($row,$col,$sheet,'align');
  506. }
  507. function bgColor($row,$col,$sheet=0) {
  508. return $this->xfProperty($row,$col,$sheet,'bgColor');
  509. }
  510. function borderLeft($row,$col,$sheet=0) {
  511. return $this->xfProperty($row,$col,$sheet,'borderLeft');
  512. }
  513. function borderRight($row,$col,$sheet=0) {
  514. return $this->xfProperty($row,$col,$sheet,'borderRight');
  515. }
  516. function borderTop($row,$col,$sheet=0) {
  517. return $this->xfProperty($row,$col,$sheet,'borderTop');
  518. }
  519. function borderBottom($row,$col,$sheet=0) {
  520. return $this->xfProperty($row,$col,$sheet,'borderBottom');
  521. }
  522. function borderLeftColor($row,$col,$sheet=0) {
  523. return $this->colors[$this->xfProperty($row,$col,$sheet,'borderLeftColor')];
  524. }
  525. function borderRightColor($row,$col,$sheet=0) {
  526. return $this->colors[$this->xfProperty($row,$col,$sheet,'borderRightColor')];
  527. }
  528. function borderTopColor($row,$col,$sheet=0) {
  529. return $this->colors[$this->xfProperty($row,$col,$sheet,'borderTopColor')];
  530. }
  531. function borderBottomColor($row,$col,$sheet=0) {
  532. return $this->colors[$this->xfProperty($row,$col,$sheet,'borderBottomColor')];
  533. }
  534.  
  535. // FONT PROPERTIES
  536. // ===============
  537. function fontRecord($row,$col,$sheet=0) {
  538. $xfRecord = $this->xfRecord($row,$col,$sheet);
  539. if ($xfRecord!=null) {
  540. $font = $xfRecord['fontIndex'];
  541. if ($font!=null) {
  542. return $this->fontRecords[$font];
  543. }
  544. }
  545. return null;
  546. }
  547. function fontProperty($row,$col,$sheet=0,$prop) {
  548. $font = $this->fontRecord($row,$col,$sheet);
  549. if ($font!=null) {
  550. return $font[$prop];
  551. }
  552. return false;
  553. }
  554. function fontIndex($row,$col,$sheet=0) {
  555. return $this->xfProperty($row,$col,$sheet,'fontIndex');
  556. }
  557. function color($row,$col,$sheet=0) {
  558. $formatColor = $this->formatColor($row,$col,$sheet);
  559. if ($formatColor!="") {
  560. return $formatColor;
  561. }
  562. $ci = $this->fontProperty($row,$col,$sheet,'color');
  563. return $this->rawColor($ci);
  564. }
  565. function rawColor($ci) {
  566. if (($ci <> 0x7FFF) && ($ci <> '')) {
  567. return $this->colors[$ci];
  568. }
  569. return "";
  570. }
  571. function bold($row,$col,$sheet=0) {
  572. return $this->fontProperty($row,$col,$sheet,'bold');
  573. }
  574. function italic($row,$col,$sheet=0) {
  575. return $this->fontProperty($row,$col,$sheet,'italic');
  576. }
  577. function underline($row,$col,$sheet=0) {
  578. return $this->fontProperty($row,$col,$sheet,'under');
  579. }
  580. function height($row,$col,$sheet=0) {
  581. return $this->fontProperty($row,$col,$sheet,'height');
  582. }
  583. function font($row,$col,$sheet=0) {
  584. return $this->fontProperty($row,$col,$sheet,'font');
  585. }
  586.  
  587. // DUMP AN HTML TABLE OF THE ENTIRE XLS DATA
  588. // =========================================
  589. function dump($row_numbers=false,$col_letters=false,$sheet=0,$table_class='excel') {
  590. $out = "<table class=\"$table_class\" cellspacing=0>";
  591. if ($col_letters) {
  592. $out .= "<thead>\n\t<tr>";
  593. if ($row_numbers) {
  594. $out .= "\n\t\t<th>&nbsp</th>";
  595. }
  596. for($i=1;$i<=$this->colcount($sheet);$i++) {
  597. $style = "width:" . ($this->colwidth($i,$sheet)*1) . "px;";
  598. if ($this->colhidden($i,$sheet)) {
  599. $style .= "display:none;";
  600. }
  601. $out .= "\n\t\t<th style=\"$style\">" . strtoupper($this->colindexes[$i]) . "</th>";
  602. }
  603. $out .= "</tr></thead>\n";
  604. }
  605.  
  606. $out .= "<tbody>\n";
  607. for($row=1;$row<=$this->rowcount($sheet);$row++) {
  608. $rowheight = $this->rowheight($row,$sheet);
  609. $style = "height:" . ($rowheight*(4/3)) . "px;";
  610. if ($this->rowhidden($row,$sheet)) {
  611. $style .= "display:none;";
  612. }
  613. $out .= "\n\t<tr style=\"$style\">";
  614. if ($row_numbers) {
  615. $out .= "\n\t\t<th>$row</th>";
  616. }
  617. for($col=1;$col<=$this->colcount($sheet);$col++) {
  618. // Account for Rowspans/Colspans
  619. $rowspan = $this->rowspan($row,$col,$sheet);
  620. $colspan = $this->colspan($row,$col,$sheet);
  621. for($i=0;$i<$rowspan;$i++) {
  622. for($j=0;$j<$colspan;$j++) {
  623. if ($i>0 || $j>0) {
  624. $this->sheets[$sheet]['cellsInfo'][$row+$i][$col+$j]['dontprint']=1;
  625. }
  626. }
  627. }
  628. if(!$this->sheets[$sheet]['cellsInfo'][$row][$col]['dontprint']) {
  629. $style = $this->style($row,$col,$sheet);
  630. if ($this->colhidden($col,$sheet)) {
  631. $style .= "display:none;";
  632. }
  633. $out .= "\n\t\t<td style=\"$style\"" . ($colspan > 1?" colspan=$colspan":"") . ($rowspan > 1?" rowspan=$rowspan":"") . ">";
  634. $val = $this->val($row,$col,$sheet);
  635. if ($val=='') { $val=" "; }
  636. else {
  637. $val = htmlentities($val);
  638. $link = $this->hyperlink($row,$col,$sheet);
  639. if ($link!='') {
  640. $val = "<a href=\"$link\">$val</a>";
  641. }
  642. }
  643. $out .= "<nobr>".nl2br($val)."</nobr>";
  644. $out .= "</td>";
  645. }
  646. }
  647. $out .= "</tr>\n";
  648. }
  649. $out .= "</tbody></table>";
  650. return $out;
  651. }
  652.  
  653. // --------------
  654. // END PUBLIC API
  655.  
  656.  
  657. var $boundsheets = array();
  658. var $formatRecords = array();
  659. var $fontRecords = array();
  660. var $xfRecords = array();
  661. var $colInfo = array();
  662. var $rowInfo = array();
  663.  
  664. var $sst = array();
  665. var $sheets = array();
  666.  
  667. var $data;
  668. var $_ole;
  669. var $_defaultEncoding = "UTF-8";
  670. var $_defaultFormat = SPREADSHEET_EXCEL_READER_DEF_NUM_FORMAT;
  671. var $_columnsFormat = array();
  672. var $_rowoffset = 1;
  673. var $_coloffset = 1;
  674.  
  675. /**
  676. * List of default date formats used by Excel
  677. */
  678. var $dateFormats = array (
  679. 0xe => "m/d/Y",
  680. 0xf => "M-d-Y",
  681. 0x10 => "d-M",
  682. 0x11 => "M-Y",
  683. 0x12 => "h:i a",
  684. 0x13 => "h:i:s a",
  685. 0x14 => "H:i",
  686. 0x15 => "H:i:s",
  687. 0x16 => "d/m/Y H:i",
  688. 0x2d => "i:s",
  689. 0x2e => "H:i:s",
  690. 0x2f => "i:s.S"
  691. );
  692.  
  693. /**
  694. * Default number formats used by Excel
  695. */
  696. var $numberFormats = array(
  697. 0x1 => "0",
  698. 0x2 => "0.00",
  699. 0x3 => "#,##0",
  700. 0x4 => "#,##0.00",
  701. 0x5 => "\$#,##0;(\$#,##0)",
  702. 0x6 => "\$#,##0;[Red](\$#,##0)",
  703. 0x7 => "\$#,##0.00;(\$#,##0.00)",
  704. 0x8 => "\$#,##0.00;[Red](\$#,##0.00)",
  705. 0x9 => "0%",
  706. 0xa => "0.00%",
  707. 0xb => "0.00E+00",
  708. 0x25 => "#,##0;(#,##0)",
  709. 0x26 => "#,##0;[Red](#,##0)",
  710. 0x27 => "#,##0.00;(#,##0.00)",
  711. 0x28 => "#,##0.00;[Red](#,##0.00)",
  712. 0x29 => "#,##0;(#,##0)", // Not exactly
  713. 0x2a => "\$#,##0;(\$#,##0)", // Not exactly
  714. 0x2b => "#,##0.00;(#,##0.00)", // Not exactly
  715. 0x2c => "\$#,##0.00;(\$#,##0.00)", // Not exactly
  716. 0x30 => "##0.0E+0"
  717. );
  718.  
  719. var $colors = Array(
  720. 0x00 => "#000000",
  721. 0x01 => "#FFFFFF",
  722. 0x02 => "#FF0000",
  723. 0x03 => "#00FF00",
  724. 0x04 => "#0000FF",
  725. 0x05 => "#FFFF00",
  726. 0x06 => "#FF00FF",
  727. 0x07 => "#00FFFF",
  728. 0x08 => "#000000",
  729. 0x09 => "#FFFFFF",
  730. 0x0A => "#FF0000",
  731. 0x0B => "#00FF00",
  732. 0x0C => "#0000FF",
  733. 0x0D => "#FFFF00",
  734. 0x0E => "#FF00FF",
  735. 0x0F => "#00FFFF",
  736. 0x10 => "#800000",
  737. 0x11 => "#008000",
  738. 0x12 => "#000080",
  739. 0x13 => "#808000",
  740. 0x14 => "#800080",
  741. 0x15 => "#008080",
  742. 0x16 => "#C0C0C0",
  743. 0x17 => "#808080",
  744. 0x18 => "#9999FF",
  745. 0x19 => "#993366",
  746. 0x1A => "#FFFFCC",
  747. 0x1B => "#CCFFFF",
  748. 0x1C => "#660066",
  749. 0x1D => "#FF8080",
  750. 0x1E => "#0066CC",
  751. 0x1F => "#CCCCFF",
  752. 0x20 => "#000080",
  753. 0x21 => "#FF00FF",
  754. 0x22 => "#FFFF00",
  755. 0x23 => "#00FFFF",
  756. 0x24 => "#800080",
  757. 0x25 => "#800000",
  758. 0x26 => "#008080",
  759. 0x27 => "#0000FF",
  760. 0x28 => "#00CCFF",
  761. 0x29 => "#CCFFFF",
  762. 0x2A => "#CCFFCC",
  763. 0x2B => "#FFFF99",
  764. 0x2C => "#99CCFF",
  765. 0x2D => "#FF99CC",
  766. 0x2E => "#CC99FF",
  767. 0x2F => "#FFCC99",
  768. 0x30 => "#3366FF",
  769. 0x31 => "#33CCCC",
  770. 0x32 => "#99CC00",
  771. 0x33 => "#FFCC00",
  772. 0x34 => "#FF9900",
  773. 0x35 => "#FF6600",
  774. 0x36 => "#666699",
  775. 0x37 => "#969696",
  776. 0x38 => "#003366",
  777. 0x39 => "#339966",
  778. 0x3A => "#003300",
  779. 0x3B => "#333300",
  780. 0x3C => "#993300",
  781. 0x3D => "#993366",
  782. 0x3E => "#333399",
  783. 0x3F => "#333333",
  784. 0x40 => "#000000",
  785. 0x41 => "#FFFFFF",
  786.  
  787. 0x43 => "#000000",
  788. 0x4D => "#000000",
  789. 0x4E => "#FFFFFF",
  790. 0x4F => "#000000",
  791. 0x50 => "#FFFFFF",
  792. 0x51 => "#000000",
  793.  
  794. 0x7FFF => "#000000"
  795. );
  796.  
  797. var $lineStyles = array(
  798. 0x00 => "",
  799. 0x01 => "Thin",
  800. 0x02 => "Medium",
  801. 0x03 => "Dashed",
  802. 0x04 => "Dotted",
  803. 0x05 => "Thick",
  804. 0x06 => "Double",
  805. 0x07 => "Hair",
  806. 0x08 => "Medium dashed",
  807. 0x09 => "Thin dash-dotted",
  808. 0x0A => "Medium dash-dotted",
  809. 0x0B => "Thin dash-dot-dotted",
  810. 0x0C => "Medium dash-dot-dotted",
  811. 0x0D => "Slanted medium dash-dotted"
  812. );
  813.  
  814. var $lineStylesCss = array(
  815. "Thin" => "1px solid",
  816. "Medium" => "2px solid",
  817. "Dashed" => "1px dashed",
  818. "Dotted" => "1px dotted",
  819. "Thick" => "3px solid",
  820. "Double" => "double",
  821. "Hair" => "1px solid",
  822. "Medium dashed" => "2px dashed",
  823. "Thin dash-dotted" => "1px dashed",
  824. "Medium dash-dotted" => "2px dashed",
  825. "Thin dash-dot-dotted" => "1px dashed",
  826. "Medium dash-dot-dotted" => "2px dashed",
  827. "Slanted medium dash-dotte" => "2px dashed"
  828. );
  829.  
  830. function read16bitstring($data, $start) {
  831. $len = 0;
  832. while (ord($data[$start + $len]) + ord($data[$start + $len + 1]) > 0) $len++;
  833. return substr($data, $start, $len);
  834. }
  835.  
  836. // ADDED by Matt Kruse for better formatting
  837. function _format_value($format,$num,$f) {
  838. // 49==TEXT format
  839. // http://code.google.com/p/php-excel-reader/issues/detail?id=7
  840. if ( (!$f && $format=="%s") || ($f==49) || ($format=="GENERAL") ) {
  841. return array('string'=>$num, 'formatColor'=>null);
  842. }
  843.  
  844. // Custom pattern can be POSITIVE;NEGATIVE;ZERO
  845. // The "text" option as 4th parameter is not handled
  846. $parts = explode(";",$format);
  847. $pattern = $parts[0];
  848. // Negative pattern
  849. if (count($parts)>2 && $num==0) {
  850. $pattern = $parts[2];
  851. }
  852. // Zero pattern
  853. if (count($parts)>1 && $num<0) {
  854. $pattern = $parts[1];
  855. $num = abs($num);
  856. }
  857.  
  858. $color = "";
  859. $matches = array();
  860. $color_regex = "/^\[(BLACK|BLUE|CYAN|GREEN|MAGENTA|RED|WHITE|YELLOW)\]/i";
  861. if (preg_match($color_regex,$pattern,$matches)) {
  862. $color = strtolower($matches[1]);
  863. $pattern = preg_replace($color_regex,"",$pattern);
  864. }
  865.  
  866. // In Excel formats, "_" is used to add spacing, which we can't do in HTML
  867. $pattern = preg_replace("/_./","",$pattern);
  868.  
  869. // Some non-number characters are escaped with \, which we don't need
  870. $pattern = preg_replace("/\\\/","",$pattern);
  871.  
  872. // Some non-number strings are quoted, so we'll get rid of the quotes
  873. $pattern = preg_replace("/\"/","",$pattern);
  874.  
  875. // TEMPORARY - Convert # to 0
  876. $pattern = preg_replace("/\#/","0",$pattern);
  877.  
  878. // Find out if we need comma formatting
  879. $has_commas = preg_match("/,/",$pattern);
  880. if ($has_commas) {
  881. $pattern = preg_replace("/,/","",$pattern);
  882. }
  883.  
  884. // Handle Percentages
  885. if (preg_match("/\d(\%)([^\%]|$)/",$pattern,$matches)) {
  886. $num = $num * 100;
  887. $pattern = preg_replace("/(\d)(\%)([^\%]|$)/","$1%$3",$pattern);
  888. }
  889.  
  890. // Handle the number itself
  891. $number_regex = "/(\d+)(\.?)(\d*)/";
  892. if (preg_match($number_regex,$pattern,$matches)) {
  893. $left = $matches[1];
  894. $dec = $matches[2];
  895. $right = $matches[3];
  896. if ($has_commas) {
  897. $formatted = number_format($num,strlen($right));
  898. }
  899. else {
  900. $sprintf_pattern = "%1.".strlen($right)."f";
  901. $formatted = sprintf($sprintf_pattern, $num);
  902. }
  903. $pattern = preg_replace($number_regex, $formatted, $pattern);
  904. }
  905.  
  906. return array(
  907. 'string'=>$pattern,
  908. 'formatColor'=>$color
  909. );
  910. }
  911.  
  912. /**
  913. * Constructor
  914. *
  915. * Some basic initialisation
  916. */
  917. function Spreadsheet_Excel_Reader($file='',$store_extended_info=true,$outputEncoding='') {
  918. $this->_ole = new OLERead();
  919. $this->setUTFEncoder('iconv');
  920. if ($outputEncoding != '') {
  921. $this->setOutputEncoding($outputEncoding);
  922. }
  923. for ($i=1; $i<245; $i++) {
  924. $name = strtolower(( (($i-1)/26>=1)?chr(($i-1)/26+64):'') . chr(($i-1)%26+65));
  925. $this->colnames[$name] = $i;
  926. $this->colindexes[$i] = $name;
  927. }
  928. $this->store_extended_info = $store_extended_info;
  929. if ($file!="") {
  930. $this->read($file);
  931. }
  932. }
  933.  
  934. /**
  935. * Set the encoding method
  936. */
  937. function setOutputEncoding($encoding) {
  938. $this->_defaultEncoding = $encoding;
  939. }
  940.  
  941. /**
  942. * $encoder = 'iconv' or 'mb'
  943. * set iconv if you would like use 'iconv' for encode UTF-16LE to your encoding
  944. * set mb if you would like use 'mb_convert_encoding' for encode UTF-16LE to your encoding
  945. */
  946. function setUTFEncoder($encoder = 'iconv') {
  947. $this->_encoderFunction = '';
  948. if ($encoder == 'iconv') {
  949. $this->_encoderFunction = function_exists('iconv') ? 'iconv' : '';
  950. } elseif ($encoder == 'mb') {
  951. $this->_encoderFunction = function_exists('mb_convert_encoding') ? 'mb_convert_encoding' : '';
  952. }
  953. }
  954.  
  955. function setRowColOffset($iOffset) {
  956. $this->_rowoffset = $iOffset;
  957. $this->_coloffset = $iOffset;
  958. }
  959.  
  960. /**
  961. * Set the default number format
  962. */
  963. function setDefaultFormat($sFormat) {
  964. $this->_defaultFormat = $sFormat;
  965. }
  966.  
  967. /**
  968. * Force a column to use a certain format
  969. */
  970. function setColumnFormat($column, $sFormat) {
  971. $this->_columnsFormat[$column] = $sFormat;
  972. }
  973.  
  974. /**
  975. * Read the spreadsheet file using OLE, then parse
  976. */
  977. function read($sFileName) {
  978. $res = $this->_ole->read($sFileName);
  979.  
  980. // oops, something goes wrong (Darko Miljanovic)
  981. if($res === false) {
  982. // check error code
  983. if($this->_ole->error == 1) {
  984. // bad file
  985. die('The filename ' . $sFileName . ' is not readable');
  986. }
  987. // check other error codes here (eg bad fileformat, etc...)
  988. }
  989. $this->data = $this->_ole->getWorkBook();
  990. $this->_parse();
  991. }
  992.  
  993. /**
  994. * Parse a workbook
  995. *
  996. * @access private
  997. * @return bool
  998. */
  999. function _parse() {
  1000. $pos = 0;
  1001. $data = $this->data;
  1002.  
  1003. $code = v($data,$pos);
  1004. $length = v($data,$pos+2);
  1005. $version = v($data,$pos+4);
  1006. $substreamType = v($data,$pos+6);
  1007.  
  1008. $this->version = $version;
  1009.  
  1010. if (($version != SPREADSHEET_EXCEL_READER_BIFF8) &&
  1011. ($version != SPREADSHEET_EXCEL_READER_BIFF7)) {
  1012. return false;
  1013. }
  1014.  
  1015. if ($substreamType != SPREADSHEET_EXCEL_READER_WORKBOOKGLOBALS){
  1016. return false;
  1017. }
  1018.  
  1019. $pos += $length + 4;
  1020.  
  1021. $code = v($data,$pos);
  1022. $length = v($data,$pos+2);
  1023.  
  1024. while ($code != SPREADSHEET_EXCEL_READER_TYPE_EOF) {
  1025. switch ($code) {
  1026. case SPREADSHEET_EXCEL_READER_TYPE_SST:
  1027. $spos = $pos + 4;
  1028. $limitpos = $spos + $length;
  1029. $uniqueStrings = $this->_GetInt4d($data, $spos+4);
  1030. $spos += 8;
  1031. for ($i = 0; $i < $uniqueStrings; $i++) {
  1032. // Read in the number of characters
  1033. if ($spos == $limitpos) {
  1034. $opcode = v($data,$spos);
  1035. $conlength = v($data,$spos+2);
  1036. if ($opcode != 0x3c) {
  1037. return -1;
  1038. }
  1039. $spos += 4;
  1040. $limitpos = $spos + $conlength;
  1041. }
  1042. $numChars = ord($data[$spos]) | (ord($data[$spos+1]) << 8);
  1043. $spos += 2;
  1044. $optionFlags = ord($data[$spos]);
  1045. $spos++;
  1046. $asciiEncoding = (($optionFlags & 0x01) == 0) ;
  1047. $extendedString = ( ($optionFlags & 0x04) != 0);
  1048.  
  1049. // See if string contains formatting information
  1050. $richString = ( ($optionFlags & 0x08) != 0);
  1051.  
  1052. if ($richString) {
  1053. // Read in the crun
  1054. $formattingRuns = v($data,$spos);
  1055. $spos += 2;
  1056. }
  1057.  
  1058. if ($extendedString) {
  1059. // Read in cchExtRst
  1060. $extendedRunLength = $this->_GetInt4d($data, $spos);
  1061. $spos += 4;
  1062. }
  1063.  
  1064. $len = ($asciiEncoding)? $numChars : $numChars*2;
  1065. if ($spos + $len < $limitpos) {
  1066. $retstr = substr($data, $spos, $len);
  1067. $spos += $len;
  1068. }
  1069. else{
  1070. // found countinue
  1071. $retstr = substr($data, $spos, $limitpos - $spos);
  1072. $bytesRead = $limitpos - $spos;
  1073. $charsLeft = $numChars - (($asciiEncoding) ? $bytesRead : ($bytesRead / 2));
  1074. $spos = $limitpos;
  1075.  
  1076. while ($charsLeft > 0){
  1077. $opcode = v($data,$spos);
  1078. $conlength = v($data,$spos+2);
  1079. if ($opcode != 0x3c) {
  1080. return -1;
  1081. }
  1082. $spos += 4;
  1083. $limitpos = $spos + $conlength;
  1084. $option = ord($data[$spos]);
  1085. $spos += 1;
  1086. if ($asciiEncoding && ($option == 0)) {
  1087. $len = min($charsLeft, $limitpos - $spos); // min($charsLeft, $conlength);
  1088. $retstr .= substr($data, $spos, $len);
  1089. $charsLeft -= $len;
  1090. $asciiEncoding = true;
  1091. }
  1092. elseif (!$asciiEncoding && ($option != 0)) {
  1093. $len = min($charsLeft * 2, $limitpos - $spos); // min($charsLeft, $conlength);
  1094. $retstr .= substr($data, $spos, $len);
  1095. $charsLeft -= $len/2;
  1096. $asciiEncoding = false;
  1097. }
  1098. elseif (!$asciiEncoding && ($option == 0)) {
  1099. // Bummer - the string starts off as Unicode, but after the
  1100. // continuation it is in straightforward ASCII encoding
  1101. $len = min($charsLeft, $limitpos - $spos); // min($charsLeft, $conlength);
  1102. for ($j = 0; $j < $len; $j++) {
  1103. $retstr .= $data[$spos + $j].chr(0);
  1104. }
  1105. $charsLeft -= $len;
  1106. $asciiEncoding = false;
  1107. }
  1108. else{
  1109. $newstr = '';
  1110. for ($j = 0; $j < strlen($retstr); $j++) {
  1111. $newstr = $retstr[$j].chr(0);
  1112. }
  1113. $retstr = $newstr;
  1114. $len = min($charsLeft * 2, $limitpos - $spos); // min($charsLeft, $conlength);
  1115. $retstr .= substr($data, $spos, $len);
  1116. $charsLeft -= $len/2;
  1117. $asciiEncoding = false;
  1118. }
  1119. $spos += $len;
  1120. }
  1121. }
  1122. $retstr = ($asciiEncoding) ? $retstr : $this->_encodeUTF16($retstr);
  1123.  
  1124. if ($richString){
  1125. $spos += 4 * $formattingRuns;
  1126. }
  1127.  
  1128. // For extended strings, skip over the extended string data
  1129. if ($extendedString) {
  1130. $spos += $extendedRunLength;
  1131. }
  1132. $this->sst[]=$retstr;
  1133. }
  1134. break;
  1135. case SPREADSHEET_EXCEL_READER_TYPE_FILEPASS:
  1136. return false;
  1137. break;
  1138. case SPREADSHEET_EXCEL_READER_TYPE_NAME:
  1139. break;
  1140. case SPREADSHEET_EXCEL_READER_TYPE_FORMAT:
  1141. $indexCode = v($data,$pos+4);
  1142. if ($version == SPREADSHEET_EXCEL_READER_BIFF8) {
  1143. $numchars = v($data,$pos+6);
  1144. if (ord($data[$pos+8]) == 0){
  1145. $formatString = substr($data, $pos+9, $numchars);
  1146. } else {
  1147. $formatString = substr($data, $pos+9, $numchars*2);
  1148. }
  1149. } else {
  1150. $numchars = ord($data[$pos+6]);
  1151. $formatString = substr($data, $pos+7, $numchars*2);
  1152. }
  1153. $this->formatRecords[$indexCode] = $formatString;
  1154. break;
  1155. case SPREADSHEET_EXCEL_READER_TYPE_FONT:
  1156. $height = v($data,$pos+4);
  1157. $option = v($data,$pos+6);
  1158. $color = v($data,$pos+8);
  1159. $weight = v($data,$pos+10);
  1160. $under = ord($data[$pos+14]);
  1161. $font = "";
  1162. // Font name
  1163. $numchars = ord($data[$pos+18]);
  1164. if ((ord($data[$pos+19]) & 1) == 0){
  1165. $font = substr($data, $pos+20, $numchars);
  1166. } else {
  1167. $font = substr($data, $pos+20, $numchars*2);
  1168. $font = $this->_encodeUTF16($font);
  1169. }
  1170. $this->fontRecords[] = array(
  1171. 'height' => $height / 20,
  1172. 'italic' => !!($option & 2),
  1173. 'color' => $color,
  1174. 'under' => !($under==0),
  1175. 'bold' => ($weight==700),
  1176. 'font' => $font,
  1177. 'raw' => $this->dumpHexData($data, $pos+3, $length)
  1178. );
  1179. break;
  1180.  
  1181. case SPREADSHEET_EXCEL_READER_TYPE_PALETTE:
  1182. $colors = ord($data[$pos+4]) | ord($data[$pos+5]) << 8;
  1183. for ($coli = 0; $coli < $colors; $coli++) {
  1184. $colOff = $pos + 2 + ($coli * 4);
  1185. $colr = ord($data[$colOff]);
  1186. $colg = ord($data[$colOff+1]);
  1187. $colb = ord($data[$colOff+2]);
  1188. $this->colors[0x07 + $coli] = '#' . $this->myhex($colr) . $this->myhex($colg) . $this->myhex($colb);
  1189. }
  1190. break;
  1191.  
  1192. case SPREADSHEET_EXCEL_READER_TYPE_XF:
  1193. $fontIndexCode = (ord($data[$pos+4]) | ord($data[$pos+5]) << 8) - 1;
  1194. $fontIndexCode = max(0,$fontIndexCode);
  1195. $indexCode = ord($data[$pos+6]) | ord($data[$pos+7]) << 8;
  1196. $alignbit = ord($data[$pos+10]) & 3;
  1197. $bgi = (ord($data[$pos+22]) | ord($data[$pos+23]) << 8) & 0x3FFF;
  1198. $bgcolor = ($bgi & 0x7F);
  1199. // $bgcolor = ($bgi & 0x3f80) >> 7;
  1200. $align = "";
  1201. if ($alignbit==3) { $align="right"; }
  1202. if ($alignbit==2) { $align="center"; }
  1203.  
  1204. $fillPattern = (ord($data[$pos+21]) & 0xFC) >> 2;
  1205. if ($fillPattern == 0) {
  1206. $bgcolor = "";
  1207. }
  1208.  
  1209. $xf = array();
  1210. $xf['formatIndex'] = $indexCode;
  1211. $xf['align'] = $align;
  1212. $xf['fontIndex'] = $fontIndexCode;
  1213. $xf['bgColor'] = $bgcolor;
  1214. $xf['fillPattern'] = $fillPattern;
  1215.  
  1216. $border = ord($data[$pos+14]) | (ord($data[$pos+15]) << 8) | (ord($data[$pos+16]) << 16) | (ord($data[$pos+17]) << 24);
  1217. $xf['borderLeft'] = $this->lineStyles[($border & 0xF)];
  1218. $xf['borderRight'] = $this->lineStyles[($border & 0xF0) >> 4];
  1219. $xf['borderTop'] = $this->lineStyles[($border & 0xF00) >> 8];
  1220. $xf['borderBottom'] = $this->lineStyles[($border & 0xF000) >> 12];
  1221.  
  1222. $xf['borderLeftColor'] = ($border & 0x7F0000) >> 16;
  1223. $xf['borderRightColor'] = ($border & 0x3F800000) >> 23;
  1224. $border = (ord($data[$pos+18]) | ord($data[$pos+19]) << 8);
  1225.  
  1226. $xf['borderTopColor'] = ($border & 0x7F);
  1227. $xf['borderBottomColor'] = ($border & 0x3F80) >> 7;
  1228.  
  1229. if (array_key_exists($indexCode, $this->dateFormats)) {
  1230. $xf['type'] = 'date';
  1231. $xf['format'] = $this->dateFormats[$indexCode];
  1232. if ($align=='') { $xf['align'] = 'right'; }
  1233. }elseif (array_key_exists($indexCode, $this->numberFormats)) {
  1234. $xf['type'] = 'number';
  1235. $xf['format'] = $this->numberFormats[$indexCode];
  1236. if ($align=='') { $xf['align'] = 'right'; }
  1237. }else{
  1238. $isdate = FALSE;
  1239. $formatstr = '';
  1240. if ($indexCode > 0){
  1241. if (isset($this->formatRecords[$indexCode]))
  1242. $formatstr = $this->formatRecords[$indexCode];
  1243. if ($formatstr!="") {
  1244. $tmp = preg_replace("/\;.*/","",$formatstr);
  1245. $tmp = preg_replace("/^\[[^\]]*\]/","",$tmp);
  1246. if (preg_match("/[^hmsday\/\-:\s\\\,AMP]/i", $tmp) == 0) { // found day and time format
  1247. $isdate = TRUE;
  1248. $formatstr = $tmp;
  1249. $formatstr = str_replace(array('AM/PM','mmmm','mmm'), array('a','F','M'), $formatstr);
  1250. // m/mm are used for both minutes and months - oh SNAP!
  1251. // This mess tries to fix for that.
  1252. // 'm' == minutes only if following h/hh or preceding s/ss
  1253. $formatstr = preg_replace("/(h:?)mm?/","$1i", $formatstr);
  1254. $formatstr = preg_replace("/mm?(:?s)/","i$1", $formatstr);
  1255. // A single 'm' = n in PHP
  1256. $formatstr = preg_replace("/(^|[^m])m([^m]|$)/", '$1n$2', $formatstr);
  1257. $formatstr = preg_replace("/(^|[^m])m([^m]|$)/", '$1n$2', $formatstr);
  1258. // else it's months
  1259. $formatstr = str_replace('mm', 'm', $formatstr);
  1260. // Convert single 'd' to 'j'
  1261. $formatstr = preg_replace("/(^|[^d])d([^d]|$)/", '$1j$2', $formatstr);
  1262. $formatstr = str_replace(array('dddd','ddd','dd','yyyy','yy','hh','h'), array('l','D','d','Y','y','H','g'), $formatstr);
  1263. $formatstr = preg_replace("/ss?/", 's', $formatstr);
  1264. }
  1265. }
  1266. }
  1267. if ($isdate){
  1268. $xf['type'] = 'date';
  1269. $xf['format'] = $formatstr;
  1270. if ($align=='') { $xf['align'] = 'right'; }
  1271. }else{
  1272. // If the format string has a 0 or # in it, we'll assume it's a number
  1273. if (preg_match("/[0#]/", $formatstr)) {
  1274. $xf['type'] = 'number';
  1275. if ($align=='') { $xf['align']='right'; }
  1276. }
  1277. else {
  1278. $xf['type'] = 'other';
  1279. }
  1280. $xf['format'] = $formatstr;
  1281. $xf['code'] = $indexCode;
  1282. }
  1283. }
  1284. $this->xfRecords[] = $xf;
  1285. break;
  1286. case SPREADSHEET_EXCEL_READER_TYPE_NINETEENFOUR:
  1287. $this->nineteenFour = (ord($data[$pos+4]) == 1);
  1288. break;
  1289. case SPREADSHEET_EXCEL_READER_TYPE_BOUNDSHEET:
  1290. $rec_offset = $this->_GetInt4d($data, $pos+4);
  1291. $rec_typeFlag = ord($data[$pos+8]);
  1292. $rec_visibilityFlag = ord($data[$pos+9]);
  1293. $rec_length = ord($data[$pos+10]);
  1294.  
  1295. if ($version == SPREADSHEET_EXCEL_READER_BIFF8){
  1296. $chartype = ord($data[$pos+11]);
  1297. if ($chartype == 0){
  1298. $rec_name = substr($data, $pos+12, $rec_length);
  1299. } else {
  1300. $rec_name = $this->_encodeUTF16(substr($data, $pos+12, $rec_length*2));
  1301. }
  1302. }elseif ($version == SPREADSHEET_EXCEL_READER_BIFF7){
  1303. $rec_name = substr($data, $pos+11, $rec_length);
  1304. }
  1305. $this->boundsheets[] = array('name'=>$rec_name,'offset'=>$rec_offset);
  1306. break;
  1307.  
  1308. }
  1309.  
  1310. $pos += $length + 4;
  1311. $code = ord($data[$pos]) | ord($data[$pos+1])<<8;
  1312. $length = ord($data[$pos+2]) | ord($data[$pos+3])<<8;
  1313. }
  1314.  
  1315. foreach ($this->boundsheets as $key=>$val){
  1316. $this->sn = $key;
  1317. $this->_parsesheet($val['offset']);
  1318. }
  1319. return true;
  1320. }
  1321.  
  1322. /**
  1323. * Parse a worksheet
  1324. */
  1325. function _parsesheet($spos) {
  1326. $cont = true;
  1327. $data = $this->data;
  1328. // read BOF
  1329. $code = ord($data[$spos]) | ord($data[$spos+1])<<8;
  1330. $length = ord($data[$spos+2]) | ord($data[$spos+3])<<8;
  1331.  
  1332. $version = ord($data[$spos + 4]) | ord($data[$spos + 5])<<8;
  1333. $substreamType = ord($data[$spos + 6]) | ord($data[$spos + 7])<<8;
  1334.  
  1335. if (($version != SPREADSHEET_EXCEL_READER_BIFF8) && ($version != SPREADSHEET_EXCEL_READER_BIFF7)) {
  1336. return -1;
  1337. }
  1338.  
  1339. if ($substreamType != SPREADSHEET_EXCEL_READER_WORKSHEET){
  1340. return -2;
  1341. }
  1342. $spos += $length + 4;
  1343. while($cont) {
  1344. $lowcode = ord($data[$spos]);
  1345. if ($lowcode == SPREADSHEET_EXCEL_READER_TYPE_EOF) break;
  1346. $code = $lowcode | ord($data[$spos+1])<<8;
  1347. $length = ord($data[$spos+2]) | ord($data[$spos+3])<<8;
  1348. $spos += 4;
  1349. $this->sheets[$this->sn]['maxrow'] = $this->_rowoffset - 1;
  1350. $this->sheets[$this->sn]['maxcol'] = $this->_coloffset - 1;
  1351. unset($this->rectype);
  1352. switch ($code) {
  1353. case SPREADSHEET_EXCEL_READER_TYPE_DIMENSION:
  1354. if (!isset($this->numRows)) {
  1355. if (($length == 10) || ($version == SPREADSHEET_EXCEL_READER_BIFF7)){
  1356. $this->sheets[$this->sn]['numRows'] = ord($data[$spos+2]) | ord($data[$spos+3]) << 8;
  1357. $this->sheets[$this->sn]['numCols'] = ord($data[$spos+6]) | ord($data[$spos+7]) << 8;
  1358. } else {
  1359. $this->sheets[$this->sn]['numRows'] = ord($data[$spos+4]) | ord($data[$spos+5]) << 8;
  1360. $this->sheets[$this->sn]['numCols'] = ord($data[$spos+10]) | ord($data[$spos+11]) << 8;
  1361. }
  1362. }
  1363. break;
  1364. case SPREADSHEET_EXCEL_READER_TYPE_MERGEDCELLS:
  1365. $cellRanges = ord($data[$spos]) | ord($data[$spos+1])<<8;
  1366. for ($i = 0; $i < $cellRanges; $i++) {
  1367. $fr = ord($data[$spos + 8*$i + 2]) | ord($data[$spos + 8*$i + 3])<<8;
  1368. $lr = ord($data[$spos + 8*$i + 4]) | ord($data[$spos + 8*$i + 5])<<8;
  1369. $fc = ord($data[$spos + 8*$i + 6]) | ord($data[$spos + 8*$i + 7])<<8;
  1370. $lc = ord($data[$spos + 8*$i + 8]) | ord($data[$spos + 8*$i + 9])<<8;
  1371. if ($lr - $fr > 0) {
  1372. $this->sheets[$this->sn]['cellsInfo'][$fr+1][$fc+1]['rowspan'] = $lr - $fr + 1;
  1373. }
  1374. if ($lc - $fc > 0) {
  1375. $this->sheets[$this->sn]['cellsInfo'][$fr+1][$fc+1]['colspan'] = $lc - $fc + 1;
  1376. }
  1377. }
  1378. break;
  1379. case SPREADSHEET_EXCEL_READER_TYPE_RK:
  1380. case SPREADSHEET_EXCEL_READER_TYPE_RK2:
  1381. $row = ord($data[$spos]) | ord($data[$spos+1])<<8;
  1382. $column = ord($data[$spos+2]) | ord($data[$spos+3])<<8;
  1383. $rknum = $this->_GetInt4d($data, $spos + 6);
  1384. $numValue = $this->_GetIEEE754($rknum);
  1385. $info = $this->_getCellDetails($spos,$numValue,$column);
  1386. $this->addcell($row, $column, $info['string'],$info);
  1387. break;
  1388. case SPREADSHEET_EXCEL_READER_TYPE_LABELSST:
  1389. $row = ord($data[$spos]) | ord($data[$spos+1])<<8;
  1390. $column = ord($data[$spos+2]) | ord($data[$spos+3])<<8;
  1391. $xfindex = ord($data[$spos+4]) | ord($data[$spos+5])<<8;
  1392. $index = $this->_GetInt4d($data, $spos + 6);
  1393. $this->addcell($row, $column, $this->sst[$index], array('xfIndex'=>$xfindex) );
  1394. break;
  1395. case SPREADSHEET_EXCEL_READER_TYPE_MULRK:
  1396. $row = ord($data[$spos]) | ord($data[$spos+1])<<8;
  1397. $colFirst = ord($data[$spos+2]) | ord($data[$spos+3])<<8;
  1398. $colLast = ord($data[$spos + $length - 2]) | ord($data[$spos + $length - 1])<<8;
  1399. $columns = $colLast - $colFirst + 1;
  1400. $tmppos = $spos+4;
  1401. for ($i = 0; $i < $columns; $i++) {
  1402. $numValue = $this->_GetIEEE754($this->_GetInt4d($data, $tmppos + 2));
  1403. $info = $this->_getCellDetails($tmppos-4,$numValue,$colFirst + $i + 1);
  1404. $tmppos += 6;
  1405. $this->addcell($row, $colFirst + $i, $info['string'], $info);
  1406. }
  1407. break;
  1408. case SPREADSHEET_EXCEL_READER_TYPE_NUMBER:
  1409. $row = ord($data[$spos]) | ord($data[$spos+1])<<8;
  1410. $column = ord($data[$spos+2]) | ord($data[$spos+3])<<8;
  1411. $tmp = unpack("ddouble", substr($data, $spos + 6, 8)); // It machine machine dependent
  1412. if ($this->isDate($spos)) {
  1413. $numValue = $tmp['double'];
  1414. }
  1415. else {
  1416. $numValue = $this->createNumber($spos);
  1417. }
  1418. $info = $this->_getCellDetails($spos,$numValue,$column);
  1419. $this->addcell($row, $column, $info['string'], $info);
  1420. break;
  1421.  
  1422. case SPREADSHEET_EXCEL_READER_TYPE_FORMULA:
  1423. case SPREADSHEET_EXCEL_READER_TYPE_FORMULA2:
  1424. $row = ord($data[$spos]) | ord($data[$spos+1])<<8;
  1425. $column = ord($data[$spos+2]) | ord($data[$spos+3])<<8;
  1426. if ((ord($data[$spos+6])==0) && (ord($data[$spos+12])==255) && (ord($data[$spos+13])==255)) {
  1427. //String formula. Result follows in a STRING record
  1428. // This row/col are stored to be referenced in that record
  1429. // http://code.google.com/p/php-excel-reader/issues/detail?id=4
  1430. $previousRow = $row;
  1431. $previousCol = $column;
  1432. } elseif ((ord($data[$spos+6])==1) && (ord($data[$spos+12])==255) && (ord($data[$spos+13])==255)) {
  1433. //Boolean formula. Result is in +2; 0=false,1=true
  1434. // http://code.google.com/p/php-excel-reader/issues/detail?id=4
  1435. if (ord($this->data[$spos+8])==1) {
  1436. $this->addcell($row, $column, "TRUE");
  1437. } else {
  1438. $this->addcell($row, $column, "FALSE");
  1439. }
  1440. } elseif ((ord($data[$spos+6])==2) && (ord($data[$spos+12])==255) && (ord($data[$spos+13])==255)) {
  1441. //Error formula. Error code is in +2;
  1442. } elseif ((ord($data[$spos+6])==3) && (ord($data[$spos+12])==255) && (ord($data[$spos+13])==255)) {
  1443. //Formula result is a null string.
  1444. $this->addcell($row, $column, '');
  1445. } else {
  1446. // result is a number, so first 14 bytes are just like a _NUMBER record
  1447. $tmp = unpack("ddouble", substr($data, $spos + 6, 8)); // It machine machine dependent
  1448. if ($this->isDate($spos)) {
  1449. $numValue = $tmp['double'];
  1450. }
  1451. else {
  1452. $numValue = $this->createNumber($spos);
  1453. }
  1454. $info = $this->_getCellDetails($spos,$numValue,$column);
  1455. $this->addcell($row, $column, $info['string'], $info);
  1456. }
  1457. break;
  1458. case SPREADSHEET_EXCEL_READER_TYPE_BOOLERR:
  1459. $row = ord($data[$spos]) | ord($data[$spos+1])<<8;
  1460. $column = ord($data[$spos+2]) | ord($data[$spos+3])<<8;
  1461. $string = ord($data[$spos+6]);
  1462. $this->addcell($row, $column, $string);
  1463. break;
  1464. case SPREADSHEET_EXCEL_READER_TYPE_STRING:
  1465. // http://code.google.com/p/php-excel-reader/issues/detail?id=4
  1466. if ($version == SPREADSHEET_EXCEL_READER_BIFF8){
  1467. // Unicode 16 string, like an SST record
  1468. $xpos = $spos;
  1469. $numChars =ord($data[$xpos]) | (ord($data[$xpos+1]) << 8);
  1470. $xpos += 2;
  1471. $optionFlags =ord($data[$xpos]);
  1472. $xpos++;
  1473. $asciiEncoding = (($optionFlags &0x01) == 0) ;
  1474. $extendedString = (($optionFlags & 0x04) != 0);
  1475. // See if string contains formatting information
  1476. $richString = (($optionFlags & 0x08) != 0);
  1477. if ($richString) {
  1478. // Read in the crun
  1479. $formattingRuns =ord($data[$xpos]) | (ord($data[$xpos+1]) << 8);
  1480. $xpos += 2;
  1481. }
  1482. if ($extendedString) {
  1483. // Read in cchExtRst
  1484. $extendedRunLength =$this->_GetInt4d($this->data, $xpos);
  1485. $xpos += 4;
  1486. }
  1487. $len = ($asciiEncoding)?$numChars : $numChars*2;
  1488. $retstr =substr($data, $xpos, $len);
  1489. $xpos += $len;
  1490. $retstr = ($asciiEncoding)? $retstr : $this->_encodeUTF16($retstr);
  1491. }
  1492. elseif ($version == SPREADSHEET_EXCEL_READER_BIFF7){
  1493. // Simple byte string
  1494. $xpos = $spos;
  1495. $numChars =ord($data[$xpos]) | (ord($data[$xpos+1]) << 8);
  1496. $xpos += 2;
  1497. $retstr =substr($data, $xpos, $numChars);
  1498. }
  1499. $this->addcell($previousRow, $previousCol, $retstr);
  1500. break;
  1501. case SPREADSHEET_EXCEL_READER_TYPE_ROW:
  1502. $row = ord($data[$spos]) | ord($data[$spos+1])<<8;
  1503. $rowInfo = ord($data[$spos + 6]) | ((ord($data[$spos+7]) << 8) & 0x7FFF);
  1504. if (($rowInfo & 0x8000) > 0) {
  1505. $rowHeight = -1;
  1506. } else {
  1507. $rowHeight = $rowInfo & 0x7FFF;
  1508. }
  1509. $rowHidden = (ord($data[$spos + 12]) & 0x20) >> 5;
  1510. $this->rowInfo[$this->sn][$row+1] = Array('height' => $rowHeight / 20, 'hidden'=>$rowHidden );
  1511. break;
  1512. case SPREADSHEET_EXCEL_READER_TYPE_DBCELL:
  1513. break;
  1514. case SPREADSHEET_EXCEL_READER_TYPE_MULBLANK:
  1515. $row = ord($data[$spos]) | ord($data[$spos+1])<<8;
  1516. $column = ord($data[$spos+2]) | ord($data[$spos+3])<<8;
  1517. $cols = ($length / 2) - 3;
  1518. for ($c = 0; $c < $cols; $c++) {
  1519. $xfindex = ord($data[$spos + 4 + ($c * 2)]) | ord($data[$spos + 5 + ($c * 2)])<<8;
  1520. $this->addcell($row, $column + $c, "", array('xfIndex'=>$xfindex));
  1521. }
  1522. break;
  1523. case SPREADSHEET_EXCEL_READER_TYPE_LABEL:
  1524. $row = ord($data[$spos]) | ord($data[$spos+1])<<8;
  1525. $column = ord($data[$spos+2]) | ord($data[$spos+3])<<8;
  1526. $this->addcell($row, $column, substr($data, $spos + 8, ord($data[$spos + 6]) | ord($data[$spos + 7])<<8));
  1527. break;
  1528. case SPREADSHEET_EXCEL_READER_TYPE_EOF:
  1529. $cont = false;
  1530. break;
  1531. case SPREADSHEET_EXCEL_READER_TYPE_HYPER:
  1532. // Only handle hyperlinks to a URL
  1533. $row = ord($this->data[$spos]) | ord($this->data[$spos+1])<<8;
  1534. $row2 = ord($this->data[$spos+2]) | ord($this->data[$spos+3])<<8;
  1535. $column = ord($this->data[$spos+4]) | ord($this->data[$spos+5])<<8;
  1536. $column2 = ord($this->data[$spos+6]) | ord($this->data[$spos+7])<<8;
  1537. $linkdata = Array();
  1538. $flags = ord($this->data[$spos + 28]);
  1539. $udesc = "";
  1540. $ulink = "";
  1541. $uloc = 32;
  1542. $linkdata['flags'] = $flags;
  1543. if (($flags & 1) > 0 ) { // is a type we understand
  1544. // is there a description ?
  1545. if (($flags & 0x14) == 0x14 ) { // has a description
  1546. $uloc += 4;
  1547. $descLen = ord($this->data[$spos + 32]) | ord($this->data[$spos + 33]) << 8;
  1548. $udesc = substr($this->data, $spos + $uloc, $descLen * 2);
  1549. $uloc += 2 * $descLen;
  1550. }
  1551. $ulink = $this->read16bitstring($this->data, $spos + $uloc + 20);
  1552. if ($udesc == "") {
  1553. $udesc = $ulink;
  1554. }
  1555. }
  1556. $linkdata['desc'] = $udesc;
  1557. $linkdata['link'] = $this->_encodeUTF16($ulink);
  1558. for ($r=$row; $r<=$row2; $r++) {
  1559. for ($c=$column; $c<=$column2; $c++) {
  1560. $this->sheets[$this->sn]['cellsInfo'][$r+1][$c+1]['hyperlink'] = $linkdata;
  1561. }
  1562. }
  1563. break;
  1564. case SPREADSHEET_EXCEL_READER_TYPE_DEFCOLWIDTH:
  1565. $this->defaultColWidth = ord($data[$spos+4]) | ord($data[$spos+5]) << 8;
  1566. break;
  1567. case SPREADSHEET_EXCEL_READER_TYPE_STANDARDWIDTH:
  1568. $this->standardColWidth = ord($data[$spos+4]) | ord($data[$spos+5]) << 8;
  1569. break;
  1570. case SPREADSHEET_EXCEL_READER_TYPE_COLINFO:
  1571. $colfrom = ord($data[$spos+0]) | ord($data[$spos+1]) << 8;
  1572. $colto = ord($data[$spos+2]) | ord($data[$spos+3]) << 8;
  1573. $cw = ord($data[$spos+4]) | ord($data[$spos+5]) << 8;
  1574. $cxf = ord($data[$spos+6]) | ord($data[$spos+7]) << 8;
  1575. $co = ord($data[$spos+8]);
  1576. for ($coli = $colfrom; $coli <= $colto; $coli++) {
  1577. $this->colInfo[$this->sn][$coli+1] = Array('width' => $cw, 'xf' => $cxf, 'hidden' => ($co & 0x01), 'collapsed' => ($co & 0x1000) >> 12);
  1578. }
  1579. break;
  1580.  
  1581. default:
  1582. break;
  1583. }
  1584. $spos += $length;
  1585. }
  1586.  
  1587. if (!isset($this->sheets[$this->sn]['numRows']))
  1588. $this->sheets[$this->sn]['numRows'] = $this->sheets[$this->sn]['maxrow'];
  1589. if (!isset($this->sheets[$this->sn]['numCols']))
  1590. $this->sheets[$this->sn]['numCols'] = $this->sheets[$this->sn]['maxcol'];
  1591. }
  1592.  
  1593. function isDate($spos) {
  1594. $xfindex = ord($this->data[$spos+4]) | ord($this->data[$spos+5]) << 8;
  1595. return ($this->xfRecords[$xfindex]['type'] == 'date');
  1596. }
  1597.  
  1598. // Get the details for a particular cell
  1599. function _getCellDetails($spos,$numValue,$column) {
  1600. $xfindex = ord($this->data[$spos+4]) | ord($this->data[$spos+5]) << 8;
  1601. $xfrecord = $this->xfRecords[$xfindex];
  1602. $type = $xfrecord['type'];
  1603.  
  1604. $format = $xfrecord['format'];
  1605. $formatIndex = $xfrecord['formatIndex'];
  1606. $fontIndex = $xfrecord['fontIndex'];
  1607. $formatColor = "";
  1608. $rectype = '';
  1609. $string = '';
  1610. $raw = '';
  1611.  
  1612. if (isset($this->_columnsFormat[$column + 1])){
  1613. $format = $this->_columnsFormat[$column + 1];
  1614. }
  1615.  
  1616. if ($type == 'date') {
  1617. // See http://groups.google.com/group/php-excel-reader-discuss/browse_frm/thread/9c3f9790d12d8e10/f2045c2369ac79de
  1618. $rectype = 'date';
  1619. // Convert numeric value into a date
  1620. $utcDays = floor($numValue - ($this->nineteenFour ? SPREADSHEET_EXCEL_READER_UTCOFFSETDAYS1904 : SPREADSHEET_EXCEL_READER_UTCOFFSETDAYS));
  1621. $utcValue = ($utcDays) * SPREADSHEET_EXCEL_READER_MSINADAY;
  1622. $dateinfo = gmgetdate($utcValue);
  1623.  
  1624. $raw = $numValue;
  1625. $fractionalDay = $numValue - floor($numValue) + .0000001; // The .0000001 is to fix for php/excel fractional diffs
  1626.  
  1627. $totalseconds = floor(SPREADSHEET_EXCEL_READER_MSINADAY * $fractionalDay);
  1628. $secs = $totalseconds % 60;
  1629. $totalseconds -= $secs;
  1630. $hours = floor($totalseconds / (60 * 60));
  1631. $mins = floor($totalseconds / 60) % 60;
  1632. $string = date ($format, mktime($hours, $mins, $secs, $dateinfo["mon"], $dateinfo["mday"], $dateinfo["year"]));
  1633. } else if ($type == 'number') {
  1634. $rectype = 'number';
  1635. $formatted = $this->_format_value($format, $numValue, $formatIndex);
  1636. $string = $formatted['string'];
  1637. $formatColor = $formatted['formatColor'];
  1638. $raw = $numValue;
  1639. } else{
  1640. if ($format=="") {
  1641. $format = $this->_defaultFormat;
  1642. }
  1643. $rectype = 'unknown';
  1644. $formatted = $this->_format_value($format, $numValue, $formatIndex);
  1645. $string = $formatted['string'];
  1646. $formatColor = $formatted['formatColor'];
  1647. $raw = $numValue;
  1648. }
  1649.  
  1650. return array(
  1651. 'string'=>$string,
  1652. 'raw'=>$raw,
  1653. 'rectype'=>$rectype,
  1654. 'format'=>$format,
  1655. 'formatIndex'=>$formatIndex,
  1656. 'fontIndex'=>$fontIndex,
  1657. 'formatColor'=>$formatColor,
  1658. 'xfIndex'=>$xfindex
  1659. );
  1660.  
  1661. }
  1662.  
  1663.  
  1664. function createNumber($spos) {
  1665. $rknumhigh = $this->_GetInt4d($this->data, $spos + 10);
  1666. $rknumlow = $this->_GetInt4d($this->data, $spos + 6);
  1667. $sign = ($rknumhigh & 0x80000000) >> 31;
  1668. $exp = ($rknumhigh & 0x7ff00000) >> 20;
  1669. $mantissa = (0x100000 | ($rknumhigh & 0x000fffff));
  1670. $mantissalow1 = ($rknumlow & 0x80000000) >> 31;
  1671. $mantissalow2 = ($rknumlow & 0x7fffffff);
  1672. $value = $mantissa / pow( 2 , (20- ($exp - 1023)));
  1673. if ($mantissalow1 != 0) $value += 1 / pow (2 , (21 - ($exp - 1023)));
  1674. $value += $mantissalow2 / pow (2 , (52 - ($exp - 1023)));
  1675. if ($sign) {$value = -1 * $value;}
  1676. return $value;
  1677. }
  1678.  
  1679. function addcell($row, $col, $string, $info=null) {
  1680. $this->sheets[$this->sn]['maxrow'] = max($this->sheets[$this->sn]['maxrow'], $row + $this->_rowoffset);
  1681. $this->sheets[$this->sn]['maxcol'] = max($this->sheets[$this->sn]['maxcol'], $col + $this->_coloffset);
  1682. $this->sheets[$this->sn]['cells'][$row + $this->_rowoffset][$col + $this->_coloffset] = $string;
  1683. if ($this->store_extended_info && $info) {
  1684. foreach ($info as $key=>$val) {
  1685. $this->sheets[$this->sn]['cellsInfo'][$row + $this->_rowoffset][$col + $this->_coloffset][$key] = $val;
  1686. }
  1687. }
  1688. }
  1689.  
  1690.  
  1691. function _GetIEEE754($rknum) {
  1692. if (($rknum & 0x02) != 0) {
  1693. $value = $rknum >> 2;
  1694. } else {
  1695. //mmp
  1696. // I got my info on IEEE754 encoding from
  1697. // http://research.microsoft.com/~hollasch/cgindex/coding/ieeefloat.html
  1698. // The RK format calls for using only the most significant 30 bits of the
  1699. // 64 bit floating point value. The other 34 bits are assumed to be 0
  1700. // So, we use the upper 30 bits of $rknum as follows...
  1701. $sign = ($rknum & 0x80000000) >> 31;
  1702. $exp = ($rknum & 0x7ff00000) >> 20;
  1703. $mantissa = (0x100000 | ($rknum & 0x000ffffc));
  1704. $value = $mantissa / pow( 2 , (20- ($exp - 1023)));
  1705. if ($sign) {
  1706. $value = -1 * $value;
  1707. }
  1708. //end of changes by mmp
  1709. }
  1710. if (($rknum & 0x01) != 0) {
  1711. $value /= 100;
  1712. }
  1713. return $value;
  1714. }
  1715.  
  1716. function _encodeUTF16($string) {
  1717. $result = $string;
  1718. if ($this->_defaultEncoding){
  1719. switch ($this->_encoderFunction){
  1720. case 'iconv' : $result = iconv('UTF-16LE', $this->_defaultEncoding, $string);
  1721. break;
  1722. case 'mb_convert_encoding' : $result = mb_convert_encoding($string, $this->_defaultEncoding, 'UTF-16LE' );
  1723. break;
  1724. }
  1725. }
  1726. return $result;
  1727. }
  1728.  
  1729. function _GetInt4d($data, $pos) {
  1730. $value = ord($data[$pos]) | (ord($data[$pos+1]) << 8) | (ord($data[$pos+2]) << 16) | (ord($data[$pos+3]) << 24);
  1731. if ($value>=4294967294) {
  1732. $value=-2;
  1733. }
  1734. return $value;
  1735. }
  1736.  
  1737. }
  1738.  
  1739. ?>
Ahmad fatony budiman
commented on 17 Mei 2017 11:16:48
  1. Untuk databasenya
  2.  
  3.  
  4. nama varchar(100)
  5. telepon varchar(100)
  6. creation_date date
  7.  
  8. semoga bermanfaat
Maaf, Untuk Memberikan Komentar Anda Harus Login !!!