Sfoglia il codice sorgente

Merge pull request #198 from viest/dev

Feat: xlsx to csv
viest 5 anni fa
parent
commit
6d5abe0675

+ 7 - 8
README.md

@@ -16,7 +16,7 @@
 <a href="https://app.fossa.io/projects/git%2Bgithub.com%2Fviest%2Fphp-ext-xlswriter?ref=badge_shield"><img src="https://app.fossa.io/api/projects/git%2Bgithub.com%2Fviest%2Fphp-ext-xlswriter.svg?type=shield"/></a>
 </div>
 
-#### Why use xlswriter
+## Why use xlswriter
 
 Please refer to the image below. PHPExcel has been unable to work properly for memory reasons at 40,000 and 100000 points, but it can be resolved by modifying the ini configuration, but the time may take longer to complete the work;
 
@@ -64,21 +64,21 @@ Test environment: Macbook Pro 13 inch, Intel Core i5, 16GB 2133MHz LPDDR3 Memory
 * Full mode: Just 3S, the memory is only 558MB;
 * Cursor mode: Just 2.8S, memory is only <1MB;
 
-#### Documents
+## Documents
 
 [文档|Documents](https://xlswriter-docs.viest.me/)
 
-#### PECL Repository
+## PECL Repository
 
 [![pecl](resource/pecl.png)](https://pecl.php.net/package/xlswriter)
 
-#### IDE Helper
+## IDE Helper
 
 ```bash
 composer require viest/php-ext-xlswriter-ide-helper:dev-master
 ```
 
-#### Exchange group
+## Exchange group
 
 <img width="160" src="resource/qq.jpg"/>
 
@@ -112,9 +112,8 @@ Support this project with your organization. Your logo will show up here with a
 <a href="https://opencollective.com/php-ext-xlswriter/organization/8/website"><img src="https://opencollective.com/php-ext-xlswriter/organization/8/avatar.svg"></a>
 <a href="https://opencollective.com/php-ext-xlswriter/organization/9/website"><img src="https://opencollective.com/php-ext-xlswriter/organization/9/avatar.svg"></a>
 
-#### License
-
-FreeBSD license
+## License
 
+BSD License
 
 [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fviest%2Fphp-ext-xlswriter.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fviest%2Fphp-ext-xlswriter?ref=badge_large)

+ 1 - 0
config.m4

@@ -24,6 +24,7 @@ if test "$PHP_XLSWRITER" != "no"; then
 
     xls_read_sources="
     kernel/read.c \
+    kernel/csv.c \
     "
 
     minizip_sources="

+ 18 - 0
include/csv.h

@@ -0,0 +1,18 @@
+/*
+  +----------------------------------------------------------------------+
+  | XlsWriter Extension                                                  |
+  +----------------------------------------------------------------------+
+  | Copyright (c) 2017-2018 The Viest                                    |
+  +----------------------------------------------------------------------+
+  | http://www.viest.me                                                  |
+  +----------------------------------------------------------------------+
+  | Author: viest <[email protected]>                                 |
+  +----------------------------------------------------------------------+
+*/
+
+#ifndef PHP_EXT_XLS_WRITER_CSV_H
+#define PHP_EXT_XLS_WRITER_CSV_H
+
+unsigned int xlsx_to_csv(zval *stream_resource, xlsxioreadersheet sheet_t, zval *zv_type_arr_t, unsigned int flag);
+
+#endif // PHP_EXT_XLS_WRITER_CSV_H

+ 1 - 0
include/xlswriter.h

@@ -37,6 +37,7 @@
 #ifdef ENABLE_READER
 #include "xlsxio_read.h"
 #include "read.h"
+#include "csv.h"
 
 typedef struct {
     xlsxioreader      file_t;

+ 58 - 0
kernel/csv.c

@@ -0,0 +1,58 @@
+/*
+  +----------------------------------------------------------------------+
+  | XlsWriter Extension                                                  |
+  +----------------------------------------------------------------------+
+  | Copyright (c) 2017-2018 The Viest                                    |
+  +----------------------------------------------------------------------+
+  | http://www.viest.me                                                  |
+  +----------------------------------------------------------------------+
+  | Author: viest <[email protected]>                                 |
+  +----------------------------------------------------------------------+
+*/
+
+#include "xlswriter.h"
+#include "php_streams.h"
+#include "ext/standard/file.h"
+
+/* {{{ */
+unsigned int xlsx_to_csv(zval *stream_resource, xlsxioreadersheet sheet_t, zval *zv_type_arr_t, unsigned int flag)
+{
+    zval *_zv_type_arr_t = NULL;
+    php_stream *_stream_t;
+
+    ssize_t ret;
+    char delimiter = ',';
+    char enclosure = '"';
+    int escape_char = (unsigned char) '\\';
+
+    ZEND_ASSERT(Z_TYPE_P(stream_resource) == IS_RESOURCE);
+
+    if (((_stream_t) = (php_stream *)zend_fetch_resource2((Z_RES_P(stream_resource)),
+            "stream", php_file_le_stream(), php_file_le_pstream())) == NULL) {
+        return XLSWRITER_FALSE;
+	}
+
+    if (Z_TYPE_P(zv_type_arr_t) == IS_ARRAY) {
+        _zv_type_arr_t = zv_type_arr_t;
+    }
+
+    zval _zv_tmp_row;
+    ZVAL_NULL(&_zv_tmp_row);
+
+    while (sheet_read_row(sheet_t))
+    {
+        load_sheet_current_row_data(sheet_t, &_zv_tmp_row, _zv_type_arr_t, flag);
+        ret = php_fputcsv(_stream_t, &_zv_tmp_row, delimiter, enclosure, escape_char);
+
+        zend_hash_clean(Z_ARRVAL(_zv_tmp_row));
+
+        if (ret < 0) {
+            return XLSWRITER_FALSE;
+        }
+    }
+
+    zval_dtor(&_zv_tmp_row);
+
+    return XLSWRITER_TRUE;
+}
+/* }}} */

+ 31 - 0
kernel/excel.c

@@ -163,6 +163,10 @@ ZEND_BEGIN_ARG_INFO_EX(xls_open_sheet_arginfo, 0, 0, 1)
                 ZEND_ARG_INFO(0, zs_sheet_name)
 ZEND_END_ARG_INFO()
 
+ZEND_BEGIN_ARG_INFO_EX(xls_put_csv_arginfo, 0, 0, 1)
+                ZEND_ARG_INFO(0, fp)
+ZEND_END_ARG_INFO()
+
 ZEND_BEGIN_ARG_INFO_EX(xls_set_type_arginfo, 0, 0, 1)
                 ZEND_ARG_INFO(0, zv_type_t)
 ZEND_END_ARG_INFO()
@@ -924,6 +928,32 @@ PHP_METHOD(vtiful_xls, setType)
 }
 /* }}} */
 
+/** {{{ \Vtiful\Kernel\Excel::putCSV()
+ */
+PHP_METHOD(vtiful_xls, putCSV)
+{
+    zval *fp = NULL, *zv_type = NULL;;
+
+    ZEND_PARSE_PARAMETERS_START(1, 1)
+            Z_PARAM_RESOURCE(fp)
+    ZEND_PARSE_PARAMETERS_END();
+
+    xls_object *obj = Z_XLS_P(getThis());
+
+    if (!obj->read_ptr.sheet_t) {
+        RETURN_FALSE;
+    }
+
+    zv_type = zend_read_property(vtiful_xls_ce, getThis(), ZEND_STRL(V_XLS_TYPE), 0, NULL);
+
+    if (xlsx_to_csv(fp, obj->read_ptr.sheet_t, zv_type, READ_SKIP_ROW) == XLSWRITER_TRUE) {
+        RETURN_TRUE;
+    }
+
+    RETURN_FALSE;
+}
+/* }}} */
+
 /** {{{ \Vtiful\Kernel\Excel::getSheetData()
  */
 PHP_METHOD(vtiful_xls, getSheetData)
@@ -1037,6 +1067,7 @@ zend_function_entry xls_methods[] = {
 #ifdef ENABLE_READER
         PHP_ME(vtiful_xls, openFile,         xls_open_file_arginfo,          ZEND_ACC_PUBLIC)
         PHP_ME(vtiful_xls, openSheet,        xls_open_sheet_arginfo,         ZEND_ACC_PUBLIC)
+        PHP_ME(vtiful_xls, putCSV,           xls_put_csv_arginfo,            ZEND_ACC_PUBLIC)
         PHP_ME(vtiful_xls, sheetList,        NULL,                           ZEND_ACC_PUBLIC)
         PHP_ME(vtiful_xls, setType,          xls_set_type_arginfo,           ZEND_ACC_PUBLIC)
         PHP_ME(vtiful_xls, getSheetData,     NULL,                           ZEND_ACC_PUBLIC)

+ 2 - 0
package.xml

@@ -200,6 +200,8 @@
    <file md5sum="12ff3ae17d729bbfd48c87a087544924" name="tests/sheet_add.phpt" role="test" />
    <file md5sum="98f47ea5e8aab04af809a1707a1f1476" name="tests/sheet_checkout.phpt" role="test" />
    <file md5sum="5811dd930d7b0f916c662139ff1053d4" name="tests/string_from_column_index.phpt" role="test" />
+   <file name="tests/xlsx_to_csv.phpt" role="test" />
+   <file name="tests/zoom.phpt" role="test" />
    <file md5sum="f4a2d1a28ad1bf782502d698de0b1907" name="tests/include/skipif.inc" role="test" />
    <file md5sum="bb4256831dfd81f951bd6f4afbe1719f" name="CREDITS" role="doc" />
    <file md5sum="601a053cb6f200a24303ac8d3627361c" name="README.md" role="doc" />

+ 8 - 1
tests/open_xlsx_get_data_skip_empty.phpt

@@ -40,13 +40,20 @@ var_dump($data);
 @unlink(__DIR__ . '/tutorial.xlsx');
 ?>
 --EXPECT--
-array(2) {
+array(3) {
   [0]=>
   array(1) {
     [0]=>
     string(4) "Cost"
   }
   [1]=>
+  array(2) {
+    [0]=>
+    string(0) ""
+    [1]=>
+    string(0) ""
+  }
+  [2]=>
   array(1) {
     [0]=>
     string(5) "viest"

+ 6 - 0
tests/open_xlsx_next_row_skip_empty.phpt

@@ -54,6 +54,12 @@ array(1) {
   [0]=>
   string(4) "Cost"
 }
+array(2) {
+  [0]=>
+  string(0) ""
+  [1]=>
+  string(0) ""
+}
 array(1) {
   [0]=>
   string(5) "viest"

+ 2 - 2
tests/open_xlsx_next_row_with_data_type_date_array_index.phpt

@@ -38,13 +38,13 @@ array(2) {
 }
 array(2) {
   [0]=>
-  string(5) "viest"
+  string(0) ""
   [1]=>
   string(0) ""
 }
 array(5) {
   [0]=>
-  string(0) ""
+  string(5) "viest"
   [1]=>
   string(0) ""
   [2]=>

+ 33 - 0
tests/xlsx_to_csv.phpt

@@ -0,0 +1,33 @@
+--TEST--
+Check for vtiful presence
+--SKIPIF--
+<?php
+require __DIR__ . '/include/skipif.inc';
+skip_disable_reader();
+?>
+--FILE--
+<?php
+$config   = ['path' => './tests'];
+$excel    = new \Vtiful\Kernel\Excel($config);
+$filePath = $excel->fileName('tutorial.xlsx', 'TestSheet1')
+    ->header(['Item', 'Cost'])
+    ->data([
+        ['Item_1', 'Cost_1', 10, 10.9999995],
+    ])
+    ->output();
+
+$fp = fopen('./tests/file.csv', 'w');
+
+$csvResult = $excel->openFile('tutorial.xlsx')
+    ->openSheet()
+    ->putCSV($fp);
+
+var_dump($csvResult);
+?>
+--CLEAN--
+<?php
+@unlink(__DIR__ . '/tutorial.xlsx');
+@unlink(__DIR__ . '/file.csv');
+?>
+--EXPECT--
+bool(true)