Explorar o código

FEAT(const_memory): Large file export

viest %!s(int64=7) %!d(string=hai) anos
pai
achega
078b47b15d
Modificáronse 5 ficheiros con 58 adicións e 13 borrados
  1. 1 0
      config.m4
  2. 1 1
      config.w32
  3. 19 0
      kernel/common.c
  4. 35 12
      kernel/excel.c
  5. 2 0
      kernel/include.h

+ 1 - 0
config.m4

@@ -5,6 +5,7 @@ if test "$PHP_EXCEL_WRITER" != "no"; then
     excel_writer_sources="excel_writer.c \
     kernel/exception.c \
     kernel/resource.c \
+    kernel/common.c \
     "
 
     AC_MSG_CHECKING([Check libxlsxwriter support])

+ 1 - 1
config.w32

@@ -10,7 +10,7 @@ if (PHP_EXCEL_WRITER != "no") {
         CHECK_HEADER_ADD_INCLUDE("packager.h", "CFLAGS_EXCEL_WRITER", PHP_PHP_BUILD + "\\MSVCLibXlsxWriter\\libxlsxwriter\\include\\xlsxwriter;" + PHP_EXCEL_WRITER) &&
         CHECK_HEADER_ADD_INCLUDE("format.h", "CFLAGS_EXCEL_WRITER", PHP_PHP_BUILD + "\\MSVCLibXlsxWriter\\libxlsxwriter\\include\\xlsxwriter;" + PHP_EXCEL_WRITER)) {
         EXTENSION("excel_writer", "excel_writer.c")
-        ADD_SOURCES(configure_module_dirname + "\\kernel", "resource.c exception.c excel.c write.c format.c", "excel_writer");
+        ADD_SOURCES(configure_module_dirname + "\\kernel", "common.c resource.c exception.c excel.c write.c format.c", "excel_writer");
     } else {
         WARNING("excel_writer not enabled, LibXlsxWriter.lib or headers not found");
     }

+ 19 - 0
kernel/common.c

@@ -0,0 +1,19 @@
+#include "include.h"
+
+void excel_file_path(zend_string *file_name, zval *dir_path, zval *file_path)
+{
+    zend_string *full_path, *zstr_path;
+
+    zstr_path = zval_get_string(dir_path);
+
+    if (Z_STRVAL_P(dir_path)[Z_STRLEN_P(dir_path)-1] == '/') {
+        full_path = zend_string_extend(zstr_path, ZSTR_LEN(zstr_path) + ZSTR_LEN(file_name), 0);
+        memcpy(ZSTR_VAL(full_path)+ZSTR_LEN(zstr_path), ZSTR_VAL(file_name), ZSTR_LEN(file_name)+1);
+    } else {
+        full_path = zend_string_extend(zstr_path, ZSTR_LEN(zstr_path) + ZSTR_LEN(file_name) + 1, 0);
+        ZSTR_VAL(full_path)[ZSTR_LEN(zstr_path)] ='/';
+        memcpy(ZSTR_VAL(full_path)+ZSTR_LEN(zstr_path)+1, ZSTR_VAL(file_name), ZSTR_LEN(file_name)+1);
+    }
+
+    ZVAL_STR(file_path, full_path);
+}

+ 35 - 12
kernel/excel.c

@@ -108,7 +108,7 @@ PHP_METHOD(vtiful_excel, __construct)
 PHP_METHOD(vtiful_excel, fileName)
 {
     zval rv, file_path, handle, *config, *tmp_path;
-    zend_string *file_name, *full_path, *zstr_path;
+    zend_string *file_name;
 
     ZEND_PARSE_PARAMETERS_START(1, 1)
             Z_PARAM_STR(file_name)
@@ -119,20 +119,41 @@ PHP_METHOD(vtiful_excel, fileName)
     config   = zend_read_property(vtiful_excel_ce, return_value, ZEND_STRL(V_EXCEL_COF), 0, &rv TSRMLS_DC);
     tmp_path = zend_hash_str_find(Z_ARRVAL_P(config), V_EXCEL_PAT, sizeof(V_EXCEL_PAT)-1);
 
-    zstr_path = zval_get_string(tmp_path);
+    excel_file_path(file_name, tmp_path, &file_path);
 
-    if (Z_STRVAL_P(tmp_path)[Z_STRLEN_P(tmp_path)-1] == '/') {
-        full_path = zend_string_extend(zstr_path, ZSTR_LEN(zstr_path) + ZSTR_LEN(file_name), 0);
-        memcpy(ZSTR_VAL(full_path)+ZSTR_LEN(zstr_path), ZSTR_VAL(file_name), ZSTR_LEN(file_name)+1);
-    } else {
-        full_path = zend_string_extend(zstr_path, ZSTR_LEN(zstr_path) + ZSTR_LEN(file_name) + 1, 0);
-        ZSTR_VAL(full_path)[ZSTR_LEN(zstr_path)] ='/';
-        memcpy(ZSTR_VAL(full_path)+ZSTR_LEN(zstr_path)+1, ZSTR_VAL(file_name), ZSTR_LEN(file_name)+1);
-    }
+    excel_res->workbook  = workbook_new(Z_STRVAL(file_path));
+    excel_res->worksheet = workbook_add_worksheet(excel_res->workbook, NULL);
 
-    ZVAL_STR(&file_path, full_path);
+    ZVAL_RES(&handle, zend_register_resource(excel_res, le_excel_writer));
 
-    excel_res->workbook  = workbook_new(Z_STRVAL(file_path));
+    zend_update_property(vtiful_excel_ce, return_value, ZEND_STRL(V_EXCEL_FIL), &file_path);
+    zend_update_property(vtiful_excel_ce, return_value, ZEND_STRL(V_EXCEL_HANDLE), &handle);
+
+    zval_ptr_dtor(&file_path);
+}
+/* }}} */
+
+/** {{{ \Vtiful\Kernel\Excel::constMemory(string $fileName)
+ */
+PHP_METHOD(vtiful_excel, constMemory)
+{
+    zval rv, file_path, handle, *config, *tmp_path;
+    zend_string *file_name;
+
+    ZEND_PARSE_PARAMETERS_START(1, 1)
+            Z_PARAM_STR(file_name)
+    ZEND_PARSE_PARAMETERS_END();
+
+    ZVAL_COPY(return_value, getThis());
+
+    config   = zend_read_property(vtiful_excel_ce, return_value, ZEND_STRL(V_EXCEL_COF), 0, &rv TSRMLS_DC);
+    tmp_path = zend_hash_str_find(Z_ARRVAL_P(config), V_EXCEL_PAT, sizeof(V_EXCEL_PAT)-1);
+
+    excel_file_path(file_name, tmp_path, &file_path);
+
+    lxw_workbook_options options = {.constant_memory = LXW_TRUE, .tmpdir = NULL};
+
+    excel_res->workbook  = workbook_new_opt(Z_STRVAL(file_path), &options);
     excel_res->worksheet = workbook_add_worksheet(excel_res->workbook, NULL);
 
     ZVAL_RES(&handle, zend_register_resource(excel_res, le_excel_writer));
@@ -144,6 +165,7 @@ PHP_METHOD(vtiful_excel, fileName)
 }
 /* }}} */
 
+
 /** {{{ \Vtiful\Kernel\Excel::header(array $header)
  */
 PHP_METHOD(vtiful_excel, header)
@@ -405,6 +427,7 @@ PHP_METHOD(vtiful_excel, setRow)
 zend_function_entry excel_methods[] = {
         PHP_ME(vtiful_excel, __construct,   excel_construct_arginfo,      ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
         PHP_ME(vtiful_excel, fileName,      excel_file_name_arginfo,      ZEND_ACC_PUBLIC)
+        PHP_ME(vtiful_excel, constMemory,   excel_file_name_arginfo,      ZEND_ACC_PUBLIC)
         PHP_ME(vtiful_excel, header,        excel_header_arginfo,         ZEND_ACC_PUBLIC)
         PHP_ME(vtiful_excel, data,          excel_data_arginfo,           ZEND_ACC_PUBLIC)
         PHP_ME(vtiful_excel, output,        NULL,                         ZEND_ACC_PUBLIC)

+ 2 - 0
kernel/include.h

@@ -52,4 +52,6 @@ void set_column(zend_string *range, double width, excel_resource_t *res, lxw_for
 void set_row(zend_string *range, double height, excel_resource_t *res, lxw_format *format);
 lxw_error workbook_file(excel_resource_t *self, zval *handle);
 
+void excel_file_path(zend_string *file_name, zval *dir_path, zval *file_path);
+
 #endif