feat: 安装xls插件

master
yin5th 2023-09-28 14:29:15 +08:00
parent 7e2f3cc909
commit dacfe1b5b4
47 changed files with 3059 additions and 169 deletions

View File

@ -40,7 +40,8 @@
"alipaysdk/easysdk": "^2.2",
"topthink/think-swoole": "^3.1",
"phpoffice/phpspreadsheet": "^1.19",
"yly-openapi/yly-openapi-sdk": "^1.0"
"yly-openapi/yly-openapi-sdk": "^1.0",
"mk-j/php_xlsxwriter": "^0.39.0"
},
"require-dev": {
"symfony/var-dumper": "^4.2",
@ -55,7 +56,10 @@
}
},
"config": {
"preferred-install": "dist"
"preferred-install": "dist",
"allow-plugins": {
"easywechat-composer/easywechat-composer": true
}
},
"scripts": {
"post-autoload-dump": [

40
server/composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "4bbc7dc400675f35f7f788a5d233b492",
"content-hash": "d9ec16906092528de6a3bf06cb281ef3",
"packages": [
{
"name": "adbario/php-dot-notation",
@ -1527,6 +1527,42 @@
},
"time": "2021-07-01T19:01:15+00:00"
},
{
"name": "mk-j/php_xlsxwriter",
"version": "0.39",
"dist": {
"type": "zip",
"url": "https://mirrors.cloud.tencent.com/repository/composer/mk-j/php_xlsxwriter/0.39/mk-j-php_xlsxwriter-0.39.zip",
"reference": "67541cff96eab25563aa7fcecba33e03368fa464",
"shasum": ""
},
"require": {
"ext-zip": "*",
"php": ">=5.2.1"
},
"require-dev": {
"phpunit/phpunit": "4.3.*"
},
"type": "project",
"autoload": {
"classmap": [
"xlsxwriter.class.php"
]
},
"license": [
"MIT"
],
"description": "PHP Library to write XLSX files",
"homepage": "https://github.com/mk-j/PHP_XLSXWriter",
"keywords": [
"excel",
"library",
"php",
"xls",
"xlsx"
],
"time": "2023-05-31T22:17:46+00:00"
},
{
"name": "monolog/monolog",
"version": "2.2.0",
@ -5237,5 +5273,5 @@
"ext-bcmath": "*"
},
"platform-dev": [],
"plugin-api-version": "2.1.0"
"plugin-api-version": "2.3.0"
}

View File

@ -2,6 +2,24 @@
// autoload.php @generated by Composer
if (PHP_VERSION_ID < 50600) {
if (!headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
if (!ini_get('display_errors')) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, $err);
} elseif (!headers_sent()) {
echo $err;
}
}
trigger_error(
$err,
E_USER_ERROR
);
}
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit89c8a151cf27b567cd0b0fc6ee27341c::getLoader();

View File

@ -42,30 +42,79 @@ namespace Composer\Autoload;
*/
class ClassLoader
{
/** @var \Closure(string):void */
private static $includeFile;
/** @var ?string */
private $vendorDir;
// PSR-4
/**
* @var array[]
* @psalm-var array<string, array<string, int>>
*/
private $prefixLengthsPsr4 = array();
/**
* @var array[]
* @psalm-var array<string, array<int, string>>
*/
private $prefixDirsPsr4 = array();
/**
* @var array[]
* @psalm-var array<string, string>
*/
private $fallbackDirsPsr4 = array();
// PSR-0
/**
* @var array[]
* @psalm-var array<string, array<string, string[]>>
*/
private $prefixesPsr0 = array();
/**
* @var array[]
* @psalm-var array<string, string>
*/
private $fallbackDirsPsr0 = array();
/** @var bool */
private $useIncludePath = false;
/**
* @var string[]
* @psalm-var array<string, string>
*/
private $classMap = array();
/** @var bool */
private $classMapAuthoritative = false;
/**
* @var bool[]
* @psalm-var array<string, bool>
*/
private $missingClasses = array();
/** @var ?string */
private $apcuPrefix;
/**
* @var self[]
*/
private static $registeredLoaders = array();
/**
* @param ?string $vendorDir
*/
public function __construct($vendorDir = null)
{
$this->vendorDir = $vendorDir;
self::initializeIncludeClosure();
}
/**
* @return string[]
*/
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
@ -75,28 +124,47 @@ class ClassLoader
return array();
}
/**
* @return array[]
* @psalm-return array<string, array<int, string>>
*/
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
/**
* @return array[]
* @psalm-return array<string, string>
*/
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
/**
* @return array[]
* @psalm-return array<string, string>
*/
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
/**
* @return string[] Array of classname => path
* @psalm-return array<string, string>
*/
public function getClassMap()
{
return $this->classMap;
}
/**
* @param array $classMap Class to filename map
* @param string[] $classMap Class to filename map
* @psalm-param array<string, string> $classMap
*
* @return void
*/
public function addClassMap(array $classMap)
{
@ -111,9 +179,11 @@ class ClassLoader
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
* @param string $prefix The prefix
* @param string[]|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*
* @return void
*/
public function add($prefix, $paths, $prepend = false)
{
@ -156,11 +226,13 @@ class ClassLoader
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param string[]|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
@ -204,8 +276,10 @@ class ClassLoader
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 base directories
* @param string $prefix The prefix
* @param string[]|string $paths The PSR-0 base directories
*
* @return void
*/
public function set($prefix, $paths)
{
@ -220,10 +294,12 @@ class ClassLoader
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param string[]|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function setPsr4($prefix, $paths)
{
@ -243,6 +319,8 @@ class ClassLoader
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*
* @return void
*/
public function setUseIncludePath($useIncludePath)
{
@ -265,6 +343,8 @@ class ClassLoader
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
*
* @return void
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
@ -285,6 +365,8 @@ class ClassLoader
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
*
* @param string|null $apcuPrefix
*
* @return void
*/
public function setApcuPrefix($apcuPrefix)
{
@ -305,6 +387,8 @@ class ClassLoader
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*
* @return void
*/
public function register($prepend = false)
{
@ -324,6 +408,8 @@ class ClassLoader
/**
* Unregisters this instance as an autoloader.
*
* @return void
*/
public function unregister()
{
@ -343,7 +429,8 @@ class ClassLoader
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
includeFile($file);
$includeFile = self::$includeFile;
$includeFile($file);
return true;
}
@ -403,6 +490,11 @@ class ClassLoader
return self::$registeredLoaders;
}
/**
* @param string $class
* @param string $ext
* @return string|false
*/
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
@ -468,14 +560,26 @@ class ClassLoader
return false;
}
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*/
function includeFile($file)
{
include $file;
/**
* @return void
*/
private static function initializeIncludeClosure()
{
if (self::$includeFile !== null) {
return;
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*
* @param string $file
* @return void
*/
self::$includeFile = \Closure::bind(static function($file) {
include $file;
}, null, null);
}
}

View File

@ -20,12 +20,27 @@ use Composer\Semver\VersionParser;
*
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
*
* To require it's presence, you can require `composer-runtime-api ^2.0`
* To require its presence, you can require `composer-runtime-api ^2.0`
*
* @final
*/
class InstalledVersions
{
/**
* @var mixed[]|null
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
*/
private static $installed;
/**
* @var bool|null
*/
private static $canGetVendors;
/**
* @var array[]
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static $installedByVendor = array();
/**
@ -228,7 +243,7 @@ class InstalledVersions
/**
* @return array
* @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string}
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
*/
public static function getRootPackage()
{
@ -242,7 +257,7 @@ class InstalledVersions
*
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
* @return array[]
* @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string}>}
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
*/
public static function getRawData()
{
@ -265,7 +280,7 @@ class InstalledVersions
* Returns the raw data of all installed.php which are currently loaded for custom implementations
*
* @return array[]
* @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string}>}>
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
public static function getAllRawData()
{
@ -288,7 +303,7 @@ class InstalledVersions
* @param array[] $data A vendor/composer/installed.php data set
* @return void
*
* @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string}>} $data
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
*/
public static function reload($data)
{
@ -298,7 +313,7 @@ class InstalledVersions
/**
* @return array[]
* @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string}>}>
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static function getInstalled()
{

View File

@ -2,7 +2,7 @@
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
@ -80,4 +80,6 @@ return array(
'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
'XLSXWriter' => $vendorDir . '/mk-j/php_xlsxwriter/xlsxwriter.class.php',
'XLSXWriter_BuffererWriter' => $vendorDir . '/mk-j/php_xlsxwriter/xlsxwriter.class.php',
);

View File

@ -2,21 +2,20 @@
// autoload_files.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php',
'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
'7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php',
'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
'9b552a3cc426e3287cc811caefa3cf53' => $vendorDir . '/topthink/think-helper/src/helper.php',
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
'd767e4fc2dc52fe66584ab8c6684783e' => $vendorDir . '/adbario/php-dot-notation/src/helpers.php',
'65fec9ebcfbb3cbb4fd0d519687aea01' => $vendorDir . '/danielstjules/stringy/src/Create.php',
'320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
@ -31,6 +30,7 @@ return array(
'6747f579ad6817f318cc3a7e7a0abb93' => $vendorDir . '/overtrue/wechat/src/Kernel/Helpers.php',
'f67964341ef83e59f1cc6a3916599312' => $vendorDir . '/qcloud/cos-sdk-v5/src/Qcloud/Cos/Common.php',
'841780ea2e1d6545ea3a253239d59c05' => $vendorDir . '/qiniu/php-sdk/src/Qiniu/functions.php',
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
'1cfd2761b63b0a29ed23657ea394cb2d' => $vendorDir . '/topthink/think-captcha/src/helper.php',
'af46dcea2921209ac30627b964175f13' => $vendorDir . '/topthink/think-swoole/src/helpers.php',
);

View File

@ -2,7 +2,7 @@
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(

View File

@ -2,7 +2,7 @@
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(

View File

@ -25,51 +25,26 @@ class ComposerAutoloaderInit89c8a151cf27b567cd0b0fc6ee27341c
require __DIR__ . '/platform_check.php';
spl_autoload_register(array('ComposerAutoloaderInit89c8a151cf27b567cd0b0fc6ee27341c', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInit89c8a151cf27b567cd0b0fc6ee27341c', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit89c8a151cf27b567cd0b0fc6ee27341c::getInitializer($loader));
} else {
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}
$map = require __DIR__ . '/autoload_psr4.php';
foreach ($map as $namespace => $path) {
$loader->setPsr4($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
}
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit89c8a151cf27b567cd0b0fc6ee27341c::getInitializer($loader));
$loader->register(true);
if ($useStaticLoader) {
$includeFiles = Composer\Autoload\ComposerStaticInit89c8a151cf27b567cd0b0fc6ee27341c::$files;
} else {
$includeFiles = require __DIR__ . '/autoload_files.php';
}
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequire89c8a151cf27b567cd0b0fc6ee27341c($fileIdentifier, $file);
$filesToLoad = \Composer\Autoload\ComposerStaticInit89c8a151cf27b567cd0b0fc6ee27341c::$files;
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
require $file;
}
}, null, null);
foreach ($filesToLoad as $fileIdentifier => $file) {
$requireFile($fileIdentifier, $file);
}
return $loader;
}
}
function composerRequire89c8a151cf27b567cd0b0fc6ee27341c($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
require $file;
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
}
}

View File

@ -8,16 +8,15 @@ class ComposerStaticInit89c8a151cf27b567cd0b0fc6ee27341c
{
public static $files = array (
'25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php',
'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
'7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php',
'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
'9b552a3cc426e3287cc811caefa3cf53' => __DIR__ . '/..' . '/topthink/think-helper/src/helper.php',
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
'd767e4fc2dc52fe66584ab8c6684783e' => __DIR__ . '/..' . '/adbario/php-dot-notation/src/helpers.php',
'65fec9ebcfbb3cbb4fd0d519687aea01' => __DIR__ . '/..' . '/danielstjules/stringy/src/Create.php',
'320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
@ -32,6 +31,7 @@ class ComposerStaticInit89c8a151cf27b567cd0b0fc6ee27341c
'6747f579ad6817f318cc3a7e7a0abb93' => __DIR__ . '/..' . '/overtrue/wechat/src/Kernel/Helpers.php',
'f67964341ef83e59f1cc6a3916599312' => __DIR__ . '/..' . '/qcloud/cos-sdk-v5/src/Qcloud/Cos/Common.php',
'841780ea2e1d6545ea3a253239d59c05' => __DIR__ . '/..' . '/qiniu/php-sdk/src/Qiniu/functions.php',
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
'1cfd2761b63b0a29ed23657ea394cb2d' => __DIR__ . '/..' . '/topthink/think-captcha/src/helper.php',
'af46dcea2921209ac30627b964175f13' => __DIR__ . '/..' . '/topthink/think-swoole/src/helpers.php',
);
@ -566,6 +566,8 @@ class ComposerStaticInit89c8a151cf27b567cd0b0fc6ee27341c
'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
'ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
'XLSXWriter' => __DIR__ . '/..' . '/mk-j/php_xlsxwriter/xlsxwriter.class.php',
'XLSXWriter_BuffererWriter' => __DIR__ . '/..' . '/mk-j/php_xlsxwriter/xlsxwriter.class.php',
);
public static function getInitializer(ClassLoader $loader)

View File

@ -1593,6 +1593,45 @@
},
"install-path": "../markbaker/matrix"
},
{
"name": "mk-j/php_xlsxwriter",
"version": "0.39",
"version_normalized": "0.39.0.0",
"dist": {
"type": "zip",
"url": "https://mirrors.cloud.tencent.com/repository/composer/mk-j/php_xlsxwriter/0.39/mk-j-php_xlsxwriter-0.39.zip",
"reference": "67541cff96eab25563aa7fcecba33e03368fa464",
"shasum": ""
},
"require": {
"ext-zip": "*",
"php": ">=5.2.1"
},
"require-dev": {
"phpunit/phpunit": "4.3.*"
},
"time": "2023-05-31T22:17:46+00:00",
"type": "project",
"installation-source": "dist",
"autoload": {
"classmap": [
"xlsxwriter.class.php"
]
},
"license": [
"MIT"
],
"description": "PHP Library to write XLSX files",
"homepage": "https://github.com/mk-j/PHP_XLSXWriter",
"keywords": [
"excel",
"library",
"php",
"xls",
"xlsx"
],
"install-path": "../mk-j/php_xlsxwriter"
},
{
"name": "monolog/monolog",
"version": "2.2.0",

View File

@ -1,337 +1,346 @@
<?php return array(
'root' => array(
'pretty_version' => 'dev-develop',
'version' => 'dev-develop',
'name' => 'topthink/think',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '7e2f3cc9098f8c92a961355ce2253545ea1caba0',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'reference' => '857b929fe832a707e7aa09199511ca7d25d2f1d1',
'name' => 'topthink/think',
'dev' => true,
),
'versions' => array(
'adbario/php-dot-notation' => array(
'pretty_version' => '2.2.0',
'version' => '2.2.0.0',
'reference' => 'eee4fc81296531e6aafba4c2bbccfc5adab1676e',
'type' => 'library',
'install_path' => __DIR__ . '/../adbario/php-dot-notation',
'aliases' => array(),
'reference' => 'eee4fc81296531e6aafba4c2bbccfc5adab1676e',
'dev_requirement' => false,
),
'alibabacloud/client' => array(
'pretty_version' => '1.5.31',
'version' => '1.5.31.0',
'reference' => '19224d92fe27ab8ef501d77d4891e7660bc023c1',
'type' => 'library',
'install_path' => __DIR__ . '/../alibabacloud/client',
'aliases' => array(),
'reference' => '19224d92fe27ab8ef501d77d4891e7660bc023c1',
'dev_requirement' => false,
),
'alibabacloud/tea' => array(
'pretty_version' => '3.1.22',
'version' => '3.1.22.0',
'reference' => 'f9c9b2c927253a1c23a5381cc655e41311be7f65',
'type' => 'library',
'install_path' => __DIR__ . '/../alibabacloud/tea',
'aliases' => array(),
'reference' => 'f9c9b2c927253a1c23a5381cc655e41311be7f65',
'dev_requirement' => false,
),
'alibabacloud/tea-fileform' => array(
'pretty_version' => '0.3.4',
'version' => '0.3.4.0',
'reference' => '4bf0c75a045c8115aa8cb1a394bd08d8bb833181',
'type' => 'library',
'install_path' => __DIR__ . '/../alibabacloud/tea-fileform',
'aliases' => array(),
'reference' => '4bf0c75a045c8115aa8cb1a394bd08d8bb833181',
'dev_requirement' => false,
),
'alipaysdk/easysdk' => array(
'pretty_version' => '2.2.0',
'version' => '2.2.0.0',
'reference' => '7a1cfa83c7e140bded957498ea072c77611e6480',
'type' => 'library',
'install_path' => __DIR__ . '/../alipaysdk/easysdk',
'aliases' => array(),
'reference' => '7a1cfa83c7e140bded957498ea072c77611e6480',
'dev_requirement' => false,
),
'aliyuncs/oss-sdk-php' => array(
'pretty_version' => 'v2.4.2',
'version' => '2.4.2.0',
'reference' => '0c9d902c33847c07efc66c4cdf823deaea8fc2b6',
'type' => 'library',
'install_path' => __DIR__ . '/../aliyuncs/oss-sdk-php',
'aliases' => array(),
'reference' => '0c9d902c33847c07efc66c4cdf823deaea8fc2b6',
'dev_requirement' => false,
),
'bacon/bacon-qr-code' => array(
'pretty_version' => '2.0.4',
'version' => '2.0.4.0',
'reference' => 'f73543ac4e1def05f1a70bcd1525c8a157a1ad09',
'type' => 'library',
'install_path' => __DIR__ . '/../bacon/bacon-qr-code',
'aliases' => array(),
'reference' => 'f73543ac4e1def05f1a70bcd1525c8a157a1ad09',
'dev_requirement' => false,
),
'clagiordano/weblibs-configmanager' => array(
'pretty_version' => 'v1.1.0',
'version' => '1.1.0.0',
'reference' => 'ecf584f5b3a27929175ff0abdba52f0131bef795',
'type' => 'library',
'install_path' => __DIR__ . '/../clagiordano/weblibs-configmanager',
'aliases' => array(),
'reference' => 'ecf584f5b3a27929175ff0abdba52f0131bef795',
'dev_requirement' => false,
),
'danielstjules/stringy' => array(
'pretty_version' => '3.1.0',
'version' => '3.1.0.0',
'reference' => 'df24ab62d2d8213bbbe88cc36fc35a4503b4bd7e',
'type' => 'library',
'install_path' => __DIR__ . '/../danielstjules/stringy',
'aliases' => array(),
'reference' => 'df24ab62d2d8213bbbe88cc36fc35a4503b4bd7e',
'dev_requirement' => false,
),
'dasprid/enum' => array(
'pretty_version' => '1.0.3',
'version' => '1.0.3.0',
'reference' => '5abf82f213618696dda8e3bf6f64dd042d8542b2',
'type' => 'library',
'install_path' => __DIR__ . '/../dasprid/enum',
'aliases' => array(),
'reference' => '5abf82f213618696dda8e3bf6f64dd042d8542b2',
'dev_requirement' => false,
),
'easywechat-composer/easywechat-composer' => array(
'pretty_version' => '1.4.0',
'version' => '1.4.0.0',
'reference' => '93cfce1ec842b9a5b1b0791a52afd18b833f114a',
'type' => 'composer-plugin',
'install_path' => __DIR__ . '/../easywechat-composer/easywechat-composer',
'aliases' => array(),
'reference' => '93cfce1ec842b9a5b1b0791a52afd18b833f114a',
'dev_requirement' => false,
),
'endroid/qr-code' => array(
'pretty_version' => '3.9.6',
'version' => '3.9.6.0',
'reference' => '9cdd4f5d609bfc8811ca4a62b4d23eb16976242f',
'type' => 'library',
'install_path' => __DIR__ . '/../endroid/qr-code',
'aliases' => array(),
'reference' => '9cdd4f5d609bfc8811ca4a62b4d23eb16976242f',
'dev_requirement' => false,
),
'ezyang/htmlpurifier' => array(
'pretty_version' => 'v4.14.0',
'version' => '4.14.0.0',
'reference' => '12ab42bd6e742c70c0a52f7b82477fcd44e64b75',
'type' => 'library',
'install_path' => __DIR__ . '/../ezyang/htmlpurifier',
'aliases' => array(),
'reference' => '12ab42bd6e742c70c0a52f7b82477fcd44e64b75',
'dev_requirement' => false,
),
'guzzlehttp/command' => array(
'pretty_version' => '1.0.0',
'version' => '1.0.0.0',
'reference' => '2aaa2521a8f8269d6f5dfc13fe2af12c76921034',
'type' => 'library',
'install_path' => __DIR__ . '/../guzzlehttp/command',
'aliases' => array(),
'reference' => '2aaa2521a8f8269d6f5dfc13fe2af12c76921034',
'dev_requirement' => false,
),
'guzzlehttp/guzzle' => array(
'pretty_version' => '6.5.5',
'version' => '6.5.5.0',
'reference' => '9d4290de1cfd701f38099ef7e183b64b4b7b0c5e',
'type' => 'library',
'install_path' => __DIR__ . '/../guzzlehttp/guzzle',
'aliases' => array(),
'reference' => '9d4290de1cfd701f38099ef7e183b64b4b7b0c5e',
'dev_requirement' => false,
),
'guzzlehttp/guzzle-services' => array(
'pretty_version' => '1.1.3',
'version' => '1.1.3.0',
'reference' => '9e3abf20161cbf662d616cbb995f2811771759f7',
'type' => 'library',
'install_path' => __DIR__ . '/../guzzlehttp/guzzle-services',
'aliases' => array(),
'reference' => '9e3abf20161cbf662d616cbb995f2811771759f7',
'dev_requirement' => false,
),
'guzzlehttp/promises' => array(
'pretty_version' => '1.4.1',
'version' => '1.4.1.0',
'reference' => '8e7d04f1f6450fef59366c399cfad4b9383aa30d',
'type' => 'library',
'install_path' => __DIR__ . '/../guzzlehttp/promises',
'aliases' => array(),
'reference' => '8e7d04f1f6450fef59366c399cfad4b9383aa30d',
'dev_requirement' => false,
),
'guzzlehttp/psr7' => array(
'pretty_version' => '1.8.2',
'version' => '1.8.2.0',
'reference' => 'dc960a912984efb74d0a90222870c72c87f10c91',
'type' => 'library',
'install_path' => __DIR__ . '/../guzzlehttp/psr7',
'aliases' => array(),
'reference' => 'dc960a912984efb74d0a90222870c72c87f10c91',
'dev_requirement' => false,
),
'khanamiryan/qrcode-detector-decoder' => array(
'pretty_version' => '1.0.5.1',
'version' => '1.0.5.1',
'reference' => 'b96163d4f074970dfe67d4185e75e1f4541b30ca',
'type' => 'library',
'install_path' => __DIR__ . '/../khanamiryan/qrcode-detector-decoder',
'aliases' => array(),
'reference' => 'b96163d4f074970dfe67d4185e75e1f4541b30ca',
'dev_requirement' => false,
),
'league/flysystem' => array(
'pretty_version' => '1.0.70',
'version' => '1.0.70.0',
'reference' => '585824702f534f8d3cf7fab7225e8466cc4b7493',
'type' => 'library',
'install_path' => __DIR__ . '/../league/flysystem',
'aliases' => array(),
'reference' => '585824702f534f8d3cf7fab7225e8466cc4b7493',
'dev_requirement' => false,
),
'league/flysystem-cached-adapter' => array(
'pretty_version' => '1.1.0',
'version' => '1.1.0.0',
'reference' => 'd1925efb2207ac4be3ad0c40b8277175f99ffaff',
'type' => 'library',
'install_path' => __DIR__ . '/../league/flysystem-cached-adapter',
'aliases' => array(),
'reference' => 'd1925efb2207ac4be3ad0c40b8277175f99ffaff',
'dev_requirement' => false,
),
'maennchen/zipstream-php' => array(
'pretty_version' => '2.1.0',
'version' => '2.1.0.0',
'reference' => 'c4c5803cc1f93df3d2448478ef79394a5981cc58',
'type' => 'library',
'install_path' => __DIR__ . '/../maennchen/zipstream-php',
'aliases' => array(),
'reference' => 'c4c5803cc1f93df3d2448478ef79394a5981cc58',
'dev_requirement' => false,
),
'markbaker/complex' => array(
'pretty_version' => '3.0.1',
'version' => '3.0.1.0',
'reference' => 'ab8bc271e404909db09ff2d5ffa1e538085c0f22',
'type' => 'library',
'install_path' => __DIR__ . '/../markbaker/complex',
'aliases' => array(),
'reference' => 'ab8bc271e404909db09ff2d5ffa1e538085c0f22',
'dev_requirement' => false,
),
'markbaker/matrix' => array(
'pretty_version' => '3.0.0',
'version' => '3.0.0.0',
'reference' => 'c66aefcafb4f6c269510e9ac46b82619a904c576',
'type' => 'library',
'install_path' => __DIR__ . '/../markbaker/matrix',
'aliases' => array(),
'reference' => 'c66aefcafb4f6c269510e9ac46b82619a904c576',
'dev_requirement' => false,
),
'mk-j/php_xlsxwriter' => array(
'pretty_version' => '0.39',
'version' => '0.39.0.0',
'reference' => '67541cff96eab25563aa7fcecba33e03368fa464',
'type' => 'project',
'install_path' => __DIR__ . '/../mk-j/php_xlsxwriter',
'aliases' => array(),
'dev_requirement' => false,
),
'monolog/monolog' => array(
'pretty_version' => '2.2.0',
'version' => '2.2.0.0',
'reference' => '1cb1cde8e8dd0f70cc0fe51354a59acad9302084',
'type' => 'library',
'install_path' => __DIR__ . '/../monolog/monolog',
'aliases' => array(),
'reference' => '1cb1cde8e8dd0f70cc0fe51354a59acad9302084',
'dev_requirement' => false,
),
'mtdowling/cron-expression' => array(
'pretty_version' => 'v1.2.3',
'version' => '1.2.3.0',
'reference' => '9be552eebcc1ceec9776378f7dcc085246cacca6',
'type' => 'library',
'install_path' => __DIR__ . '/../mtdowling/cron-expression',
'aliases' => array(),
'reference' => '9be552eebcc1ceec9776378f7dcc085246cacca6',
'dev_requirement' => false,
),
'mtdowling/jmespath.php' => array(
'pretty_version' => '2.6.0',
'version' => '2.6.0.0',
'reference' => '42dae2cbd13154083ca6d70099692fef8ca84bfb',
'type' => 'library',
'install_path' => __DIR__ . '/../mtdowling/jmespath.php',
'aliases' => array(),
'reference' => '42dae2cbd13154083ca6d70099692fef8ca84bfb',
'dev_requirement' => false,
),
'myclabs/php-enum' => array(
'pretty_version' => '1.7.7',
'version' => '1.7.7.0',
'reference' => 'd178027d1e679832db9f38248fcc7200647dc2b7',
'type' => 'library',
'install_path' => __DIR__ . '/../myclabs/php-enum',
'aliases' => array(),
'reference' => 'd178027d1e679832db9f38248fcc7200647dc2b7',
'dev_requirement' => false,
),
'nette/php-generator' => array(
'pretty_version' => 'v3.5.4',
'version' => '3.5.4.0',
'reference' => '59bb35ed6e8da95854fbf7b7d47dce6156b42915',
'type' => 'library',
'install_path' => __DIR__ . '/../nette/php-generator',
'aliases' => array(),
'reference' => '59bb35ed6e8da95854fbf7b7d47dce6156b42915',
'dev_requirement' => false,
),
'nette/utils' => array(
'pretty_version' => 'v3.2.3',
'version' => '3.2.3.0',
'reference' => '5c36cc1ba9bb6abb8a9e425cf054e0c3fd5b9822',
'type' => 'library',
'install_path' => __DIR__ . '/../nette/utils',
'aliases' => array(),
'reference' => '5c36cc1ba9bb6abb8a9e425cf054e0c3fd5b9822',
'dev_requirement' => false,
),
'open-smf/connection-pool' => array(
'pretty_version' => 'v1.0.16',
'version' => '1.0.16.0',
'reference' => 'f70e47dbf56f1869d3207e15825cf38810b865e0',
'type' => 'library',
'install_path' => __DIR__ . '/../open-smf/connection-pool',
'aliases' => array(),
'reference' => 'f70e47dbf56f1869d3207e15825cf38810b865e0',
'dev_requirement' => false,
),
'overtrue/socialite' => array(
'pretty_version' => '2.0.23',
'version' => '2.0.23.0',
'reference' => '0bc60597b589592243f074a4d9016aabd2e9cfb2',
'type' => 'library',
'install_path' => __DIR__ . '/../overtrue/socialite',
'aliases' => array(),
'reference' => '0bc60597b589592243f074a4d9016aabd2e9cfb2',
'dev_requirement' => false,
),
'overtrue/wechat' => array(
'pretty_version' => '4.4.1',
'version' => '4.4.1.0',
'reference' => 'a31939c7393a192d1095c280ee3be254bb38e279',
'type' => 'library',
'install_path' => __DIR__ . '/../overtrue/wechat',
'aliases' => array(),
'reference' => 'a31939c7393a192d1095c280ee3be254bb38e279',
'dev_requirement' => false,
),
'phpoffice/phpspreadsheet' => array(
'pretty_version' => '1.19.0',
'version' => '1.19.0.0',
'reference' => 'a9ab55bfae02eecffb3df669a2e19ba0e2f04bbf',
'type' => 'library',
'install_path' => __DIR__ . '/../phpoffice/phpspreadsheet',
'aliases' => array(),
'reference' => 'a9ab55bfae02eecffb3df669a2e19ba0e2f04bbf',
'dev_requirement' => false,
),
'pimple/pimple' => array(
'pretty_version' => 'v3.2.3',
'version' => '3.2.3.0',
'reference' => '9e403941ef9d65d20cba7d54e29fe906db42cf32',
'type' => 'library',
'install_path' => __DIR__ . '/../pimple/pimple',
'aliases' => array(),
'reference' => '9e403941ef9d65d20cba7d54e29fe906db42cf32',
'dev_requirement' => false,
),
'psr/cache' => array(
'pretty_version' => '1.0.1',
'version' => '1.0.1.0',
'reference' => 'd11b50ad223250cf17b86e38383413f5a6764bf8',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/cache',
'aliases' => array(),
'reference' => 'd11b50ad223250cf17b86e38383413f5a6764bf8',
'dev_requirement' => false,
),
'psr/cache-implementation' => array(
@ -343,10 +352,10 @@
'psr/container' => array(
'pretty_version' => '1.0.0',
'version' => '1.0.0.0',
'reference' => 'b7ce3b176482dbbc1245ebf52b181af44c2cf55f',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/container',
'aliases' => array(),
'reference' => 'b7ce3b176482dbbc1245ebf52b181af44c2cf55f',
'dev_requirement' => false,
),
'psr/event-dispatcher-implementation' => array(
@ -358,28 +367,28 @@
'psr/http-client' => array(
'pretty_version' => '1.0.1',
'version' => '1.0.1.0',
'reference' => '2dfb5f6c5eff0e91e20e913f8c5452ed95b86621',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/http-client',
'aliases' => array(),
'reference' => '2dfb5f6c5eff0e91e20e913f8c5452ed95b86621',
'dev_requirement' => false,
),
'psr/http-factory' => array(
'pretty_version' => '1.0.1',
'version' => '1.0.1.0',
'reference' => '12ac7fcd07e5b077433f5f2bee95b3a771bf61be',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/http-factory',
'aliases' => array(),
'reference' => '12ac7fcd07e5b077433f5f2bee95b3a771bf61be',
'dev_requirement' => false,
),
'psr/http-message' => array(
'pretty_version' => '1.0.1',
'version' => '1.0.1.0',
'reference' => 'f6561bf28d520154e4b0ec72be95418abe6d9363',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/http-message',
'aliases' => array(),
'reference' => 'f6561bf28d520154e4b0ec72be95418abe6d9363',
'dev_requirement' => false,
),
'psr/http-message-implementation' => array(
@ -391,10 +400,10 @@
'psr/log' => array(
'pretty_version' => '1.1.3',
'version' => '1.1.3.0',
'reference' => '0f73288fd15629204f9d42b7055f72dacbe811fc',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/log',
'aliases' => array(),
'reference' => '0f73288fd15629204f9d42b7055f72dacbe811fc',
'dev_requirement' => false,
),
'psr/log-implementation' => array(
@ -406,10 +415,10 @@
'psr/simple-cache' => array(
'pretty_version' => '1.0.1',
'version' => '1.0.1.0',
'reference' => '408d5eafb83c57f6365a3ca330ff23aa4a5fa39b',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/simple-cache',
'aliases' => array(),
'reference' => '408d5eafb83c57f6365a3ca330ff23aa4a5fa39b',
'dev_requirement' => false,
),
'psr/simple-cache-implementation' => array(
@ -421,82 +430,82 @@
'qcloud/cos-sdk-v5' => array(
'pretty_version' => 'v2.2.0',
'version' => '2.2.0.0',
'reference' => 'e67ad8143695192ee206bcbcafc78c08da92c621',
'type' => 'library',
'install_path' => __DIR__ . '/../qcloud/cos-sdk-v5',
'aliases' => array(),
'reference' => 'e67ad8143695192ee206bcbcafc78c08da92c621',
'dev_requirement' => false,
),
'qiniu/php-sdk' => array(
'pretty_version' => 'v7.3.0',
'version' => '7.3.0.0',
'reference' => '0a461e13b09545b23df361843c6a65fdd3a26426',
'type' => 'library',
'install_path' => __DIR__ . '/../qiniu/php-sdk',
'aliases' => array(),
'reference' => '0a461e13b09545b23df361843c6a65fdd3a26426',
'dev_requirement' => false,
),
'ralouphie/getallheaders' => array(
'pretty_version' => '3.0.3',
'version' => '3.0.3.0',
'reference' => '120b605dfeb996808c31b6477290a714d356e822',
'type' => 'library',
'install_path' => __DIR__ . '/../ralouphie/getallheaders',
'aliases' => array(),
'reference' => '120b605dfeb996808c31b6477290a714d356e822',
'dev_requirement' => false,
),
'rmccue/requests' => array(
'pretty_version' => 'v1.8.1',
'version' => '1.8.1.0',
'reference' => '82e6936366eac3af4d836c18b9d8c31028fe4cd5',
'type' => 'library',
'install_path' => __DIR__ . '/../rmccue/requests',
'aliases' => array(),
'reference' => '82e6936366eac3af4d836c18b9d8c31028fe4cd5',
'dev_requirement' => false,
),
'songshenzong/support' => array(
'pretty_version' => '2.0.5',
'version' => '2.0.5.0',
'reference' => '34973c04ffcf226e503f1c3a69d30ac49f7621f6',
'type' => 'library',
'install_path' => __DIR__ . '/../songshenzong/support',
'aliases' => array(),
'reference' => '34973c04ffcf226e503f1c3a69d30ac49f7621f6',
'dev_requirement' => false,
),
'stechstudio/backoff' => array(
'pretty_version' => '1.2',
'version' => '1.2.0.0',
'reference' => '816e46107a6be2e1072ba0ff2cb26034872dfa49',
'type' => 'library',
'install_path' => __DIR__ . '/../stechstudio/backoff',
'aliases' => array(),
'reference' => '816e46107a6be2e1072ba0ff2cb26034872dfa49',
'dev_requirement' => false,
),
'swoole/ide-helper' => array(
'pretty_version' => '4.7.1',
'version' => '4.7.1.0',
'reference' => '918a98b5b264425fdb59461d9bbd7f9b504ead71',
'type' => 'library',
'install_path' => __DIR__ . '/../swoole/ide-helper',
'aliases' => array(),
'reference' => '918a98b5b264425fdb59461d9bbd7f9b504ead71',
'dev_requirement' => false,
),
'symfony/cache' => array(
'pretty_version' => 'v4.4.22',
'version' => '4.4.22.0',
'reference' => '0da1df9b1a31f328f1711b5cd922c38a15c5fc74',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/cache',
'aliases' => array(),
'reference' => '0da1df9b1a31f328f1711b5cd922c38a15c5fc74',
'dev_requirement' => false,
),
'symfony/cache-contracts' => array(
'pretty_version' => 'v1.1.10',
'version' => '1.1.10.0',
'reference' => '8d5489c10ef90aa7413e4921fc3c0520e24cbed7',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/cache-contracts',
'aliases' => array(),
'reference' => '8d5489c10ef90aa7413e4921fc3c0520e24cbed7',
'dev_requirement' => false,
),
'symfony/cache-implementation' => array(
@ -508,19 +517,19 @@
'symfony/event-dispatcher' => array(
'pretty_version' => 'v4.4.20',
'version' => '4.4.20.0',
'reference' => 'c352647244bd376bf7d31efbd5401f13f50dad0c',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/event-dispatcher',
'aliases' => array(),
'reference' => 'c352647244bd376bf7d31efbd5401f13f50dad0c',
'dev_requirement' => false,
),
'symfony/event-dispatcher-contracts' => array(
'pretty_version' => 'v1.1.9',
'version' => '1.1.9.0',
'reference' => '84e23fdcd2517bf37aecbd16967e83f0caee25a7',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/event-dispatcher-contracts',
'aliases' => array(),
'reference' => '84e23fdcd2517bf37aecbd16967e83f0caee25a7',
'dev_requirement' => false,
),
'symfony/event-dispatcher-implementation' => array(
@ -532,271 +541,271 @@
'symfony/finder' => array(
'pretty_version' => 'v4.4.30',
'version' => '4.4.30.0',
'reference' => '70362f1e112280d75b30087c7598b837c1b468b6',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/finder',
'aliases' => array(),
'reference' => '70362f1e112280d75b30087c7598b837c1b468b6',
'dev_requirement' => false,
),
'symfony/http-foundation' => array(
'pretty_version' => 'v4.4.22',
'version' => '4.4.22.0',
'reference' => '1a6f87ef99d05b1bf5c865b4ef7992263e1cb081',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/http-foundation',
'aliases' => array(),
'reference' => '1a6f87ef99d05b1bf5c865b4ef7992263e1cb081',
'dev_requirement' => false,
),
'symfony/inflector' => array(
'pretty_version' => 'v4.4.25',
'version' => '4.4.25.0',
'reference' => 'fc695ab721136b27aa84427a0fa80189761266ef',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/inflector',
'aliases' => array(),
'reference' => 'fc695ab721136b27aa84427a0fa80189761266ef',
'dev_requirement' => false,
),
'symfony/mime' => array(
'pretty_version' => 'v4.4.22',
'version' => '4.4.22.0',
'reference' => '36f2e59c90762bb09170553130a4dc1934cada58',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/mime',
'aliases' => array(),
'reference' => '36f2e59c90762bb09170553130a4dc1934cada58',
'dev_requirement' => false,
),
'symfony/options-resolver' => array(
'pretty_version' => 'v4.4.25',
'version' => '4.4.25.0',
'reference' => '2e607d627c70aa56284a02d34fc60dfe3a9a352e',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/options-resolver',
'aliases' => array(),
'reference' => '2e607d627c70aa56284a02d34fc60dfe3a9a352e',
'dev_requirement' => false,
),
'symfony/polyfill-ctype' => array(
'pretty_version' => 'v1.23.0',
'version' => '1.23.0.0',
'reference' => '46cd95797e9df938fdd2b03693b5fca5e64b01ce',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-ctype',
'aliases' => array(),
'reference' => '46cd95797e9df938fdd2b03693b5fca5e64b01ce',
'dev_requirement' => false,
),
'symfony/polyfill-intl-idn' => array(
'pretty_version' => 'v1.22.1',
'version' => '1.22.1.0',
'reference' => '2d63434d922daf7da8dd863e7907e67ee3031483',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-intl-idn',
'aliases' => array(),
'reference' => '2d63434d922daf7da8dd863e7907e67ee3031483',
'dev_requirement' => false,
),
'symfony/polyfill-intl-normalizer' => array(
'pretty_version' => 'v1.22.1',
'version' => '1.22.1.0',
'reference' => '43a0283138253ed1d48d352ab6d0bdb3f809f248',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-intl-normalizer',
'aliases' => array(),
'reference' => '43a0283138253ed1d48d352ab6d0bdb3f809f248',
'dev_requirement' => false,
),
'symfony/polyfill-mbstring' => array(
'pretty_version' => 'v1.22.0',
'version' => '1.22.0.0',
'reference' => 'f377a3dd1fde44d37b9831d68dc8dea3ffd28e13',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
'aliases' => array(),
'reference' => 'f377a3dd1fde44d37b9831d68dc8dea3ffd28e13',
'dev_requirement' => false,
),
'symfony/polyfill-php72' => array(
'pretty_version' => 'v1.22.0',
'version' => '1.22.0.0',
'reference' => 'cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php72',
'aliases' => array(),
'reference' => 'cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9',
'dev_requirement' => false,
),
'symfony/polyfill-php80' => array(
'pretty_version' => 'v1.22.0',
'version' => '1.22.0.0',
'reference' => 'dc3063ba22c2a1fd2f45ed856374d79114998f91',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php80',
'aliases' => array(),
'reference' => 'dc3063ba22c2a1fd2f45ed856374d79114998f91',
'dev_requirement' => false,
),
'symfony/property-access' => array(
'pretty_version' => 'v4.4.25',
'version' => '4.4.25.0',
'reference' => '3af7c21b4128eadbace0800b51054a81bff896c6',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/property-access',
'aliases' => array(),
'reference' => '3af7c21b4128eadbace0800b51054a81bff896c6',
'dev_requirement' => false,
),
'symfony/psr-http-message-bridge' => array(
'pretty_version' => 'v2.1.0',
'version' => '2.1.0.0',
'reference' => '81db2d4ae86e9f0049828d9343a72b9523884e5d',
'type' => 'symfony-bridge',
'install_path' => __DIR__ . '/../symfony/psr-http-message-bridge',
'aliases' => array(),
'reference' => '81db2d4ae86e9f0049828d9343a72b9523884e5d',
'dev_requirement' => false,
),
'symfony/service-contracts' => array(
'pretty_version' => 'v1.1.9',
'version' => '1.1.9.0',
'reference' => 'b776d18b303a39f56c63747bcb977ad4b27aca26',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/service-contracts',
'aliases' => array(),
'reference' => 'b776d18b303a39f56c63747bcb977ad4b27aca26',
'dev_requirement' => false,
),
'symfony/var-dumper' => array(
'pretty_version' => 'v4.4.18',
'version' => '4.4.18.0',
'reference' => '4f31364bbc8177f2a6dbc125ac3851634ebe2a03',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/var-dumper',
'aliases' => array(),
'reference' => '4f31364bbc8177f2a6dbc125ac3851634ebe2a03',
'dev_requirement' => true,
),
'symfony/var-exporter' => array(
'pretty_version' => 'v4.4.22',
'version' => '4.4.22.0',
'reference' => 'ef3054c7e878fe0837ef9ac2c5ecfddfd27dd9e9',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/var-exporter',
'aliases' => array(),
'reference' => 'ef3054c7e878fe0837ef9ac2c5ecfddfd27dd9e9',
'dev_requirement' => false,
),
'tencentcloud/tencentcloud-sdk-php' => array(
'pretty_version' => '3.0.389',
'version' => '3.0.389.0',
'reference' => 'c53cc9cd36061c0f90abf89682f209f2248dd8ff',
'type' => 'library',
'install_path' => __DIR__ . '/../tencentcloud/tencentcloud-sdk-php',
'aliases' => array(),
'reference' => 'c53cc9cd36061c0f90abf89682f209f2248dd8ff',
'dev_requirement' => false,
),
'topthink/framework' => array(
'pretty_version' => 'v6.0.7',
'version' => '6.0.7.0',
'reference' => 'db8fe22520a9660dd5e4c87e304034ac49e39270',
'type' => 'library',
'install_path' => __DIR__ . '/../topthink/framework',
'aliases' => array(),
'reference' => 'db8fe22520a9660dd5e4c87e304034ac49e39270',
'dev_requirement' => false,
),
'topthink/think' => array(
'pretty_version' => 'dev-develop',
'version' => 'dev-develop',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '7e2f3cc9098f8c92a961355ce2253545ea1caba0',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'reference' => '857b929fe832a707e7aa09199511ca7d25d2f1d1',
'dev_requirement' => false,
),
'topthink/think-captcha' => array(
'pretty_version' => 'v3.0.3',
'version' => '3.0.3.0',
'reference' => '1eef3717c1bcf4f5bbe2d1a1c704011d330a8b55',
'type' => 'library',
'install_path' => __DIR__ . '/../topthink/think-captcha',
'aliases' => array(),
'reference' => '1eef3717c1bcf4f5bbe2d1a1c704011d330a8b55',
'dev_requirement' => false,
),
'topthink/think-helper' => array(
'pretty_version' => 'v3.1.4',
'version' => '3.1.4.0',
'reference' => 'c28d37743bda4a0455286ca85b17b5791d626e10',
'type' => 'library',
'install_path' => __DIR__ . '/../topthink/think-helper',
'aliases' => array(),
'reference' => 'c28d37743bda4a0455286ca85b17b5791d626e10',
'dev_requirement' => false,
),
'topthink/think-multi-app' => array(
'pretty_version' => 'v1.0.14',
'version' => '1.0.14.0',
'reference' => 'ccaad7c2d33f42cb1cc2a78d6610aaec02cea4c3',
'type' => 'library',
'install_path' => __DIR__ . '/../topthink/think-multi-app',
'aliases' => array(),
'reference' => 'ccaad7c2d33f42cb1cc2a78d6610aaec02cea4c3',
'dev_requirement' => false,
),
'topthink/think-orm' => array(
'pretty_version' => 'v2.0.36',
'version' => '2.0.36.0',
'reference' => 'f48dc09050f25029d41a66bfc9c3c403e4f82024',
'type' => 'library',
'install_path' => __DIR__ . '/../topthink/think-orm',
'aliases' => array(),
'reference' => 'f48dc09050f25029d41a66bfc9c3c403e4f82024',
'dev_requirement' => false,
),
'topthink/think-swoole' => array(
'pretty_version' => 'v3.1.3',
'version' => '3.1.3.0',
'reference' => 'df78b1f6eb6cd8f45f49ab7b0d4cc65595181504',
'type' => 'library',
'install_path' => __DIR__ . '/../topthink/think-swoole',
'aliases' => array(),
'reference' => 'df78b1f6eb6cd8f45f49ab7b0d4cc65595181504',
'dev_requirement' => false,
),
'topthink/think-template' => array(
'pretty_version' => 'v2.0.8',
'version' => '2.0.8.0',
'reference' => 'abfc293f74f9ef5127b5c416310a01fe42e59368',
'type' => 'library',
'install_path' => __DIR__ . '/../topthink/think-template',
'aliases' => array(),
'reference' => 'abfc293f74f9ef5127b5c416310a01fe42e59368',
'dev_requirement' => false,
),
'topthink/think-trace' => array(
'pretty_version' => 'v1.4',
'version' => '1.4.0.0',
'reference' => '9a9fa8f767b6c66c5a133ad21ca1bc96ad329444',
'type' => 'library',
'install_path' => __DIR__ . '/../topthink/think-trace',
'aliases' => array(),
'reference' => '9a9fa8f767b6c66c5a133ad21ca1bc96ad329444',
'dev_requirement' => true,
),
'topthink/think-view' => array(
'pretty_version' => 'v1.0.14',
'version' => '1.0.14.0',
'reference' => 'edce0ae2c9551ab65f9e94a222604b0dead3576d',
'type' => 'library',
'install_path' => __DIR__ . '/../topthink/think-view',
'aliases' => array(),
'reference' => 'edce0ae2c9551ab65f9e94a222604b0dead3576d',
'dev_requirement' => false,
),
'xin/container' => array(
'pretty_version' => '2.0.1',
'version' => '2.0.1.0',
'reference' => '97bb67f87dd851545938a1f2fe0ffbd379e3ff81',
'type' => 'library',
'install_path' => __DIR__ . '/../xin/container',
'aliases' => array(),
'reference' => '97bb67f87dd851545938a1f2fe0ffbd379e3ff81',
'dev_requirement' => false,
),
'xin/helper' => array(
'pretty_version' => '1.0.0',
'version' => '1.0.0.0',
'reference' => '02a58132dae2aea2d1c0b8e66f55125969224747',
'type' => 'library',
'install_path' => __DIR__ . '/../xin/helper',
'aliases' => array(),
'reference' => '02a58132dae2aea2d1c0b8e66f55125969224747',
'dev_requirement' => false,
),
'yly-openapi/yly-openapi-sdk' => array(
'pretty_version' => 'v1.0.3',
'version' => '1.0.3.0',
'reference' => 'f4ca7a2296fcb7001eb154dcba1cc389837c9a27',
'type' => 'library',
'install_path' => __DIR__ . '/../yly-openapi/yly-openapi-sdk',
'aliases' => array(),
'reference' => 'f4ca7a2296fcb7001eb154dcba1cc389837c9a27',
'dev_requirement' => false,
),
),

View File

@ -0,0 +1,3 @@
vendor
.idea
examples/*.xlsx

View File

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2013 Mark Jones
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,100 @@
PHP_XLSXWriter
==============
This library is designed to be lightweight, and have minimal memory usage.
It is designed to output an Excel compatible spreadsheet in (Office 2007+) xlsx format, with just basic features supported:
* supports PHP 5.2.1+
* takes UTF-8 encoded input
* multiple worksheets
* supports currency/date/numeric cell formatting, simple formulas
* supports basic cell styling
* supports writing huge 100K+ row spreadsheets
[Never run out of memory with PHPExcel again](https://github.com/mk-j/PHP_XLSXWriter).
Simple PHP CLI example:
```php
$data = array(
array('year','month','amount'),
array('2003','1','220'),
array('2003','2','153.5'),
);
$writer = new XLSXWriter();
$writer->writeSheet($data);
$writer->writeToFile('output.xlsx');
```
Simple/Advanced Cell Formats:
```php
$header = array(
'created'=>'date',
'product_id'=>'integer',
'quantity'=>'#,##0',
'amount'=>'price',
'description'=>'string',
'tax'=>'[$$-1009]#,##0.00;[RED]-[$$-1009]#,##0.00',
);
$data = array(
array('2015-01-01',873,1,'44.00','misc','=D2*0.05'),
array('2015-01-12',324,2,'88.00','none','=D3*0.05'),
);
$writer = new XLSXWriter();
$writer->writeSheetHeader('Sheet1', $header );
foreach($data as $row)
$writer->writeSheetRow('Sheet1', $row );
$writer->writeToFile('example.xlsx');
```
50000 rows: (1.4s, 0MB memory usage)
```php
include_once("xlsxwriter.class.php");
$writer = new XLSXWriter();
$writer->writeSheetHeader('Sheet1', array('c1'=>'integer','c2'=>'integer','c3'=>'integer','c4'=>'integer') );
for($i=0; $i<50000; $i++)
{
$writer->writeSheetRow('Sheet1', array($i, $i+1, $i+2, $i+3) );
}
$writer->writeToFile('huge.xlsx');
echo '#'.floor((memory_get_peak_usage())/1024/1024)."MB"."\n";
```
| rows | time | memory |
| ------ | ---- | ------ |
| 50000 | 1.4s | 0MB |
| 100000 | 2.7s | 0MB |
| 150000 | 4.1s | 0MB |
| 200000 | 5.7s | 0MB |
| 250000 | 7.0s | 0MB |
Simple cell formats map to more advanced cell formats
| simple formats | format code |
| ---------- | ---- |
| string | @ |
| integer | 0 |
| date | YYYY-MM-DD |
| datetime | YYYY-MM-DD HH:MM:SS |
| time | HH:MM:SS |
| price | #,##0.00 |
| dollar | [$$-1009]#,##0.00;[RED]-[$$-1009]#,##0.00 |
| euro | #,##0.00 [$€-407];[RED]-#,##0.00 [$€-407] |
Basic cell styles have been available since version 0.30
| style | allowed values |
| ------------ | ---- |
| font | Arial, Times New Roman, Courier New, Comic Sans MS |
| font-size | 8,9,10,11,12 ... |
| font-style | bold, italic, underline, strikethrough or multiple ie: 'bold,italic' |
| border | left, right, top, bottom, or multiple ie: 'top,left' |
| border-style | thin, medium, thick, dashDot, dashDotDot, dashed, dotted, double, hair, mediumDashDot, mediumDashDotDot, mediumDashed, slantDashDot |
| border-color | #RRGGBB, ie: #ff99cc or #f9c |
| color | #RRGGBB, ie: #ff99cc or #f9c |
| fill | #RRGGBB, ie: #eeffee or #efe |
| halign | general, left, right, justify, center |
| valign | bottom, center, distributed |

View File

@ -0,0 +1,19 @@
{
"name": "mk-j/php_xlsxwriter",
"description": "PHP Library to write XLSX files",
"keywords": ["php", "library","xls", "xlsx", "excel"],
"type": "project",
"homepage": "https://github.com/mk-j/PHP_XLSXWriter",
"license": "MIT",
"autoload": {
"classmap": ["xlsxwriter.class.php"]
},
"require-dev": {
"phpunit/phpunit": "4.3.*"
},
"require": {
"php": ">=5.2.1",
"ext-zip": "*"
}
}

760
server/vendor/mk-j/php_xlsxwriter/composer.lock generated vendored Normal file
View File

@ -0,0 +1,760 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "89c1f54283c6b465c6b1a751a5270d78",
"packages": [],
"packages-dev": [
{
"name": "doctrine/instantiator",
"version": "1.0.4",
"source": {
"type": "git",
"url": "https://github.com/doctrine/instantiator.git",
"reference": "f976e5de371104877ebc89bd8fecb0019ed9c119"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/instantiator/zipball/f976e5de371104877ebc89bd8fecb0019ed9c119",
"reference": "f976e5de371104877ebc89bd8fecb0019ed9c119",
"shasum": ""
},
"require": {
"php": ">=5.3,<8.0-DEV"
},
"require-dev": {
"athletic/athletic": "~0.1.8",
"ext-pdo": "*",
"ext-phar": "*",
"phpunit/phpunit": "~4.0",
"squizlabs/php_codesniffer": "2.0.*@ALPHA"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-0": {
"Doctrine\\Instantiator\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Marco Pivetta",
"email": "ocramius@gmail.com",
"homepage": "http://ocramius.github.com/"
}
],
"description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
"homepage": "https://github.com/doctrine/instantiator",
"keywords": [
"constructor",
"instantiate"
],
"time": "2014-10-13 12:58:55"
},
{
"name": "phpunit/php-code-coverage",
"version": "2.0.11",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "53603b3c995f5aab6b59c8e08c3a663d2cc810b7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/53603b3c995f5aab6b59c8e08c3a663d2cc810b7",
"reference": "53603b3c995f5aab6b59c8e08c3a663d2cc810b7",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"phpunit/php-file-iterator": "~1.3",
"phpunit/php-text-template": "~1.2",
"phpunit/php-token-stream": "~1.3",
"sebastian/environment": "~1.0",
"sebastian/version": "~1.0"
},
"require-dev": {
"ext-xdebug": ">=2.1.4",
"phpunit/phpunit": "~4.1"
},
"suggest": {
"ext-dom": "*",
"ext-xdebug": ">=2.2.1",
"ext-xmlwriter": "*"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
""
],
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
}
],
"description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
"homepage": "https://github.com/sebastianbergmann/php-code-coverage",
"keywords": [
"coverage",
"testing",
"xunit"
],
"time": "2014-08-31 06:33:04"
},
{
"name": "phpunit/php-file-iterator",
"version": "1.3.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
"reference": "acd690379117b042d1c8af1fafd61bde001bf6bb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb",
"reference": "acd690379117b042d1c8af1fafd61bde001bf6bb",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"autoload": {
"classmap": [
"File/"
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
""
],
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
}
],
"description": "FilterIterator implementation that filters files based on a list of suffixes.",
"homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
"keywords": [
"filesystem",
"iterator"
],
"time": "2013-10-10 15:34:57"
},
{
"name": "phpunit/php-text-template",
"version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-text-template.git",
"reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a",
"reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"autoload": {
"classmap": [
"Text/"
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
""
],
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
}
],
"description": "Simple template engine.",
"homepage": "https://github.com/sebastianbergmann/php-text-template/",
"keywords": [
"template"
],
"time": "2014-01-30 17:20:04"
},
{
"name": "phpunit/php-timer",
"version": "1.0.5",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-timer.git",
"reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/19689d4354b295ee3d8c54b4f42c3efb69cbc17c",
"reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"autoload": {
"classmap": [
"PHP/"
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
""
],
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
}
],
"description": "Utility class for timing",
"homepage": "https://github.com/sebastianbergmann/php-timer/",
"keywords": [
"timer"
],
"time": "2013-08-02 07:42:54"
},
{
"name": "phpunit/php-token-stream",
"version": "1.3.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
"reference": "f8d5d08c56de5cfd592b3340424a81733259a876"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/f8d5d08c56de5cfd592b3340424a81733259a876",
"reference": "f8d5d08c56de5cfd592b3340424a81733259a876",
"shasum": ""
},
"require": {
"ext-tokenizer": "*",
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.2"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.3-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
}
],
"description": "Wrapper around PHP's tokenizer extension.",
"homepage": "https://github.com/sebastianbergmann/php-token-stream/",
"keywords": [
"tokenizer"
],
"time": "2014-08-31 06:12:13"
},
{
"name": "phpunit/phpunit",
"version": "4.3.5",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "2dab9d593997db4abcf58d0daf798eb4e9cecfe1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/2dab9d593997db4abcf58d0daf798eb4e9cecfe1",
"reference": "2dab9d593997db4abcf58d0daf798eb4e9cecfe1",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-json": "*",
"ext-pcre": "*",
"ext-reflection": "*",
"ext-spl": "*",
"php": ">=5.3.3",
"phpunit/php-code-coverage": "~2.0",
"phpunit/php-file-iterator": "~1.3.2",
"phpunit/php-text-template": "~1.2",
"phpunit/php-timer": "~1.0.2",
"phpunit/phpunit-mock-objects": "~2.3",
"sebastian/comparator": "~1.0",
"sebastian/diff": "~1.1",
"sebastian/environment": "~1.0",
"sebastian/exporter": "~1.0",
"sebastian/version": "~1.0",
"symfony/yaml": "~2.0"
},
"suggest": {
"phpunit/php-invoker": "~1.1"
},
"bin": [
"phpunit"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.3.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
"",
"../../symfony/yaml/"
],
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "lead"
}
],
"description": "The PHP Unit Testing framework.",
"homepage": "http://www.phpunit.de/",
"keywords": [
"phpunit",
"testing",
"xunit"
],
"time": "2014-11-11 10:11:09"
},
{
"name": "phpunit/phpunit-mock-objects",
"version": "2.3.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
"reference": "c63d2367247365f688544f0d500af90a11a44c65"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/c63d2367247365f688544f0d500af90a11a44c65",
"reference": "c63d2367247365f688544f0d500af90a11a44c65",
"shasum": ""
},
"require": {
"doctrine/instantiator": "~1.0,>=1.0.1",
"php": ">=5.3.3",
"phpunit/php-text-template": "~1.2"
},
"require-dev": {
"phpunit/phpunit": "~4.3"
},
"suggest": {
"ext-soap": "*"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.3.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
}
],
"description": "Mock Object library for PHPUnit",
"homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
"keywords": [
"mock",
"xunit"
],
"time": "2014-10-03 05:12:11"
},
{
"name": "sebastian/comparator",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git",
"reference": "e54a01c0da1b87db3c5a3c4c5277ddf331da4aef"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/e54a01c0da1b87db3c5a3c4c5277ddf331da4aef",
"reference": "e54a01c0da1b87db3c5a3c4c5277ddf331da4aef",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"sebastian/diff": "~1.1",
"sebastian/exporter": "~1.0"
},
"require-dev": {
"phpunit/phpunit": "~4.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Jeff Welch",
"email": "whatthejeff@gmail.com"
},
{
"name": "Volker Dusch",
"email": "github@wallbash.com"
},
{
"name": "Bernhard Schussek",
"email": "bschussek@2bepublished.at"
},
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
}
],
"description": "Provides the functionality to compare PHP values for equality",
"homepage": "http://www.github.com/sebastianbergmann/comparator",
"keywords": [
"comparator",
"compare",
"equality"
],
"time": "2014-05-11 23:00:21"
},
{
"name": "sebastian/diff",
"version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/diff.git",
"reference": "5843509fed39dee4b356a306401e9dd1a931fec7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/5843509fed39dee4b356a306401e9dd1a931fec7",
"reference": "5843509fed39dee4b356a306401e9dd1a931fec7",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.2"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Kore Nordmann",
"email": "mail@kore-nordmann.de"
},
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
}
],
"description": "Diff implementation",
"homepage": "http://www.github.com/sebastianbergmann/diff",
"keywords": [
"diff"
],
"time": "2014-08-15 10:29:00"
},
{
"name": "sebastian/environment",
"version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/environment.git",
"reference": "0d9bf79554d2a999da194a60416c15cf461eb67d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/0d9bf79554d2a999da194a60416c15cf461eb67d",
"reference": "0d9bf79554d2a999da194a60416c15cf461eb67d",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
}
],
"description": "Provides functionality to handle HHVM/PHP environments",
"homepage": "http://www.github.com/sebastianbergmann/environment",
"keywords": [
"Xdebug",
"environment",
"hhvm"
],
"time": "2014-10-22 06:38:05"
},
{
"name": "sebastian/exporter",
"version": "1.0.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/exporter.git",
"reference": "c7d59948d6e82818e1bdff7cadb6c34710eb7dc0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c7d59948d6e82818e1bdff7cadb6c34710eb7dc0",
"reference": "c7d59948d6e82818e1bdff7cadb6c34710eb7dc0",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Jeff Welch",
"email": "whatthejeff@gmail.com"
},
{
"name": "Volker Dusch",
"email": "github@wallbash.com"
},
{
"name": "Bernhard Schussek",
"email": "bschussek@2bepublished.at"
},
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
},
{
"name": "Adam Harvey",
"email": "aharvey@php.net"
}
],
"description": "Provides the functionality to export PHP variables for visualization",
"homepage": "http://www.github.com/sebastianbergmann/exporter",
"keywords": [
"export",
"exporter"
],
"time": "2014-09-10 00:51:36"
},
{
"name": "sebastian/version",
"version": "1.0.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/version.git",
"reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/version/zipball/b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43",
"reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43",
"shasum": ""
},
"type": "library",
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "lead"
}
],
"description": "Library that helps with managing the version number of Git-hosted PHP projects",
"homepage": "https://github.com/sebastianbergmann/version",
"time": "2014-03-07 15:35:33"
},
{
"name": "symfony/yaml",
"version": "v2.5.6",
"target-dir": "Symfony/Component/Yaml",
"source": {
"type": "git",
"url": "https://github.com/symfony/Yaml.git",
"reference": "2d9f527449cabfa8543dd7fa3a466d6ae83d6726"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Yaml/zipball/2d9f527449cabfa8543dd7fa3a466d6ae83d6726",
"reference": "2d9f527449cabfa8543dd7fa3a466d6ae83d6726",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.5-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\Yaml\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
},
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
}
],
"description": "Symfony Yaml Component",
"homepage": "http://symfony.com",
"time": "2014-10-01 05:50:18"
}
],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"platform": [],
"platform-dev": []
}

View File

@ -0,0 +1,19 @@
<?php
include_once("xlsxwriter.class.php");
ini_set('display_errors', 0);
ini_set('log_errors', 1);
error_reporting(E_ALL & ~E_NOTICE);
$filename = "example.xlsx";
$rows = array(
array('2003','1','-50.5','2010-01-01 23:00:00','2012-12-31 23:00:00'),
array('2003','=B1', '23.5','2010-01-01 00:00:00','2012-12-31 00:00:00'),
);
$writer = new XLSXWriter();
$writer->setAuthor('Some Author');
foreach($rows as $row)
$writer->writeSheetRow('Sheet1', $row);
$writer->writeToFile('example.xlsx');

View File

@ -0,0 +1,28 @@
<?php
include_once("xlsxwriter.class.php");
ini_set('display_errors', 0);
ini_set('log_errors', 1);
error_reporting(E_ALL & ~E_NOTICE);
$filename = "example.xlsx";
header('Content-disposition: attachment; filename="'.XLSXWriter::sanitize_filename($filename).'"');
header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
header('Content-Transfer-Encoding: binary');
header('Cache-Control: must-revalidate');
header('Pragma: public');
$rows = array(
array('2003','1','-50.5','2010-01-01 23:00:00','2012-12-31 23:00:00'),
array('2003','=B1', '23.5','2010-01-01 00:00:00','2012-12-31 00:00:00'),
);
$writer = new XLSXWriter();
$writer->setAuthor('Some Author');
foreach($rows as $row)
$writer->writeSheetRow('Sheet1', $row);
$writer->writeToStdOut();
//$writer->writeToFile('example.xlsx');
//echo $writer->writeToString();
exit(0);

View File

@ -0,0 +1,35 @@
<?php
set_include_path( get_include_path().PATH_SEPARATOR."..");
include_once("xlsxwriter.class.php");
$header = array(
'c1-text'=>'string',//text
'c2-text'=>'@',//text
'c3-integer'=>'integer',
'c4-integer'=>'0',
'c5-price'=>'price',
'c6-price'=>'#,##0.00',//custom
'c7-date'=>'date',
'c8-date'=>'YYYY-MM-DD',
);
$rows = array(
array('x101',102,103,104,105,106,'2018-01-07','2018-01-08'),
array('x201',202,203,204,205,206,'2018-02-07','2018-02-08'),
array('x301',302,303,304,305,306,'2018-03-07','2018-03-08'),
array('x401',402,403,404,405,406,'2018-04-07','2018-04-08'),
array('x501',502,503,504,505,506,'2018-05-07','2018-05-08'),
array('x601',602,603,604,605,606,'2018-06-07','2018-06-08'),
array('x701',702,703,704,705,706,'2018-07-07','2018-07-08'),
);
$writer = new XLSXWriter();
$writer->writeSheetHeader('Sheet1', $header);
foreach($rows as $row)
$writer->writeSheetRow('Sheet1', $row);
//$writer->writeSheet($rows,'Sheet1', $header);//or write the whole sheet in 1 call
$writer->writeToFile('xlsx-simple.xlsx');
//$writer->writeToStdOut();
//echo $writer->writeToString();

View File

@ -0,0 +1,34 @@
<?php
set_include_path( get_include_path().PATH_SEPARATOR."..");
include_once("xlsxwriter.class.php");
$header = array(
'year'=>'string',
'month'=>'string',
'amount'=>'price',
'first_event'=>'datetime',
'second_event'=>'date',
);
$data1 = array(
array('2003','1','-50.5','2010-01-01 23:00:00','2012-12-31 23:00:00'),
array('2003','=B2', '23.5','2010-01-01 00:00:00','2012-12-31 00:00:00'),
array('2003',"'=B2", '23.5','2010-01-01 00:00:00','2012-12-31 00:00:00'),
);
$data2 = array(
array('2003','01','343.12','4000000000'),
array('2003','02','345.12','2000000000'),
);
$writer = new XLSXWriter();
$writer->writeSheetHeader('Sheet1', $header);
foreach($data1 as $row)
$writer->writeSheetRow('Sheet1', $row);
foreach($data2 as $row)
$writer->writeSheetRow('Sheet2', $row);
$writer->writeToFile('xlsx-sheets.xlsx');
//$writer->writeToStdOut();
//echo $writer->writeToString();
exit(0);

View File

@ -0,0 +1,65 @@
<?php
set_include_path( get_include_path().PATH_SEPARATOR."..");
include_once("xlsxwriter.class.php");
$sheet1header = array(
'c1-string'=>'string',
'c2-integer'=>'integer',
'c3-custom-integer'=>'0',
'c4-custom-1decimal'=>'0.0',
'c5-custom-2decimal'=>'0.00',
'c6-custom-percent'=>'0%',
'c7-custom-percent1'=>'0.0%',
'c8-custom-percent2'=>'0.00%',
'c9-custom-text'=>'@',//text
);
$sheet2header = array(
'col1-date'=>'date',
'col2-datetime'=>'datetime',
'col3-time'=>'time',
'custom-date1'=>'YYYY-MM-DD',
'custom-date2'=>'MM/DD/YYYY',
'custom-date3'=>'DD-MMM-YYYY HH:MM AM/PM',
'custom-date4'=>'MM/DD/YYYY HH:MM:SS',
'custom-date5'=>'YYYY-MM-DD HH:MM:SS',
'custom-date6'=>'YY MMMM',
'custom-date7'=>'QQ YYYY',
'custom-time1'=>'HH:MM',
'custom-time2'=>'HH:MM:SS',
);
$sheet3header = array(
'col1-dollar'=>'dollar',
'col2-euro'=>'euro',
'custom-amount1'=>'0',
'custom-amount2'=>'0.0',//1 decimal place
'custom-amount3'=>'0.00',//2 decimal places
'custom-currency1'=>'#,##0.00',//currency 2 decimal places, no currency/dollar sign
'custom-currency2'=>'[$$-1009]#,##0.00;[RED]-[$$-1009]#,##0.00',//w/dollar sign
'custom-currency3'=>'#,##0.00 [$€-407];[RED]-#,##0.00 [$€-407]',//w/euro sign
'custom-currency4'=>'[$¥-411]#,##0;[RED]-[$¥-411]#,##0', //japanese yen
'custom-scientific'=>'0.00E+000',//-1.23E+003 scientific notation
);
$pi = 3.14159;
$date = '2018-12-31 23:59:59';
$time = '23:59:59';
$amount = '5120.5';
$writer = new XLSXWriter();
$writer->setAuthor('Some Author');
$writer->writeSheetHeader('BasicFormats',$sheet1header);
$writer->writeSheetRow('BasicFormats',array($pi,$pi,$pi,$pi,$pi,$pi,$pi,$pi,$pi) );
$writer->writeSheetHeader('Dates',$sheet2header);
$writer->writeSheetRow('Dates',array($date,$date,$date,$date,$date,$date,$date,$date,$date,$date,$time,$time) );
$writer->writeSheetHeader('Currencies',$sheet3header);
$writer->writeSheetRow('Currencies',array($amount,$amount,$amount,$amount,$amount,$amount,$amount,$amount,$amount) );
$writer->writeToFile('xlsx-formats.xlsx');
//$writer->writeToStdOut();
//echo $writer->writeToString();
echo '#'.floor((memory_get_peak_usage())/1024/1024)."MB"."\n";
exit(0);

View File

@ -0,0 +1,29 @@
<?php
set_include_path( get_include_path().PATH_SEPARATOR."..");
include_once("xlsxwriter.class.php");
$writer = new XLSXWriter();
$styles1 = array( 'font'=>'Arial','font-size'=>10,'font-style'=>'bold', 'fill'=>'#eee', 'halign'=>'center', 'border'=>'left,right,top,bottom');
$styles2 = array( ['font-size'=>6],['font-size'=>8],['font-size'=>10],['font-size'=>16] );
$styles3 = array( ['font'=>'Arial'],['font'=>'Courier New'],['font'=>'Times New Roman'],['font'=>'Comic Sans MS']);
$styles4 = array( ['font-style'=>'bold'],['font-style'=>'italic'],['font-style'=>'underline'],['font-style'=>'strikethrough']);
$styles5 = array( ['color'=>'#f00'],['color'=>'#0f0'],['color'=>'#00f'],['color'=>'#666']);
$styles6 = array( ['fill'=>'#ffc'],['fill'=>'#fcf'],['fill'=>'#ccf'],['fill'=>'#cff']);
$styles7 = array( 'border'=>'left,right,top,bottom');
$styles8 = array( ['halign'=>'left'],['halign'=>'right'],['halign'=>'center'],['halign'=>'none']);
$styles9 = array( array(),['border'=>'left,top,bottom'],['border'=>'top,bottom'],['border'=>'top,bottom,right']);
$writer->writeSheetRow('Sheet1', $rowdata = array(300,234,456,789), $styles1 );
$writer->writeSheetRow('Sheet1', $rowdata = array(300,234,456,789), $styles2 );
$writer->writeSheetRow('Sheet1', $rowdata = array(300,234,456,789), $styles3 );
$writer->writeSheetRow('Sheet1', $rowdata = array(300,234,456,789), $styles4 );
$writer->writeSheetRow('Sheet1', $rowdata = array(300,234,456,789), $styles5 );
$writer->writeSheetRow('Sheet1', $rowdata = array(300,234,456,789), $styles6 );
$writer->writeSheetRow('Sheet1', $rowdata = array(300,234,456,789), $styles7 );
$writer->writeSheetRow('Sheet1', $rowdata = array(300,234,456,789), $styles8 );
$writer->writeSheetRow('Sheet1', $rowdata = array(300,234,456,789), $styles9 );
$writer->writeToFile('xlsx-styles.xlsx');

View File

@ -0,0 +1,18 @@
<?php
set_include_path( get_include_path().PATH_SEPARATOR."..");
include_once("xlsxwriter.class.php");
$writer = new XLSXWriter();
$colors = array('ff','cc','99','66','33','00');
foreach($colors as $b) {
foreach($colors as $g) {
$rowdata = array();
$rowstyle = array();
foreach($colors as $r) {
$rowdata[] = "#$r$g$b";
$rowstyle[] = array('fill'=>"#$r$g$b");
}
$writer->writeSheetRow('Sheet1', $rowdata, $rowstyle );
}
}
$writer->writeToFile('xlsx-colors.xlsx');

View File

@ -0,0 +1,14 @@
<?php
set_include_path( get_include_path().PATH_SEPARATOR."..");
include_once("xlsxwriter.class.php");
$header = array('c1'=>'integer','c2'=>'integer','c3'=>'integer','c4'=>'integer');
$writer = new XLSXWriter();
$writer->writeSheetHeader('Sheet1', $header);
for($i=0; $i<250000; $i++)
{
$writer->writeSheetRow('Sheet1', array(rand()%10000,rand()%10000,rand()%10000,rand()%10000) );
}
$writer->writeToFile('xlsx-numbers-250k.xlsx');
echo '#'.floor((memory_get_peak_usage())/1024/1024)."MB"."\n";

View File

@ -0,0 +1,25 @@
<?php
set_include_path( get_include_path().PATH_SEPARATOR."..");
include_once("xlsxwriter.class.php");
$chars = "abcdefghijklmnopqrstuvwxyz0123456789 ";
$s = '';
for($j=0; $j<16192;$j++)
$s.= $chars[rand()%36];
$header = array('c1'=>'string','c2'=>'string','c3'=>'string','c4'=>'string');
$writer = new XLSXWriter();
$writer->writeSheetHeader('Sheet1', $header);
for($i=0; $i<250000; $i++)
{
$s1 = substr($s, rand()%4000, rand()%5+5);
$s2 = substr($s, rand()%8000, rand()%5+5);
$s3 = substr($s, rand()%12000, rand()%5+5);
$s4 = substr($s, rand()%16000, rand()%5+5);
$writer->writeSheetRow('Sheet1', array($s1, $s2, $s3, $s4) );
}
$writer->writeToFile('xlsx-strings-250k.xlsx');
echo '#'.floor((memory_get_peak_usage())/1024/1024)."MB"."\n";

View File

@ -0,0 +1,19 @@
<?php
set_include_path( get_include_path().PATH_SEPARATOR."..");
include_once("xlsxwriter.class.php");
$header = array(
"col1"=>"string",
"col2"=>"string",
"col3"=>"string",
"col4"=>"string",
);
$writer = new XLSXWriter();
$writer->writeSheetHeader('Sheet1', $header, $col_options = ['widths'=>[10,20,30,40]] );
$writer->writeSheetRow('Sheet1', $rowdata = array(300,234,456,789), $row_options = ['height'=>20] );
$writer->writeSheetRow('Sheet1', $rowdata = array(300,234,456,789), $row_options = ['height'=>30] );
$writer->writeSheetRow('Sheet1', $rowdata = array(300,234,456,789), $row_options = ['height'=>40] );
$writer->writeToFile('xlsx-widths.xlsx');

View File

@ -0,0 +1,54 @@
<?php
set_include_path( get_include_path().PATH_SEPARATOR."..");
include_once("xlsxwriter.class.php");
$writer = new XLSXWriter();
$keywords = array('some','interesting','keywords');
$writer->setTitle('Some Title');
$writer->setSubject('Some Subject');
$writer->setAuthor('Some Author');
$writer->setCompany('Some Company');
$writer->setKeywords($keywords);
$writer->setDescription('Some interesting description');
$writer->setTempDir(sys_get_temp_dir());//set custom tempdir
//----
$sheet1 = 'merged_cells';
$header = array("string","string","string","string","string");
$rows = array(
array("Merge Cells Example"),
array(100, 200, 300, 400, 500),
array(110, 210, 310, 410, 510),
);
$writer->writeSheetHeader($sheet1, $header, $col_options = ['suppress_row'=>true] );
foreach($rows as $row)
$writer->writeSheetRow($sheet1, $row);
$writer->markMergedCell($sheet1, $start_row=0, $start_col=0, $end_row=0, $end_col=4);
//----
$sheet2 = 'utf8';
$rows = array(
array('Spreadsheet','_'),
array("Hoja de cálculo", "Hoja de c\xc3\xa1lculo"),
array("Електронна таблица", "\xd0\x95\xd0\xbb\xd0\xb5\xd0\xba\xd1\x82\xd1\x80\xd0\xbe\xd0\xbd\xd0\xbd\xd0\xb0 \xd1\x82\xd0\xb0\xd0\xb1\xd0\xbb\xd0\xb8\xd1\x86\xd0\xb0"),//utf8 encoded
array("電子試算表", "\xe9\x9b\xbb\xe5\xad\x90\xe8\xa9\xa6\xe7\xae\x97\xe8\xa1\xa8"),//utf8 encoded
);
$writer->writeSheet($rows, $sheet2);
//----
$sheet3 = 'fonts';
$format = array('font'=>'Arial','font-size'=>10,'font-style'=>'bold,italic', 'fill'=>'#eee','color'=>'#f00','fill'=>'#ffc', 'border'=>'top,bottom', 'halign'=>'center');
$writer->writeSheetRow($sheet3, $row=array(101,102,103,104,105,106,107,108,109,110), $format);
$writer->writeSheetRow($sheet3, $row=array(201,202,203,204,205,206,207,208,209,210), $format);
//----
$sheet4 = 'row_options';
$writer->writeSheetHeader($sheet4, ["col1"=>"string", "col2"=>"string"], $col_options = array('widths'=>[10,10]) );
$writer->writeSheetRow($sheet4, array(101,'this text will wrap' ), $row_options = array('height'=>30,'wrap_text'=>true));
$writer->writeSheetRow($sheet4, array(201,'this text is hidden' ), $row_options = array('height'=>30,'hidden'=>true));
$writer->writeSheetRow($sheet4, array(301,'this text will not wrap'), $row_options = array('height'=>30,'collapsed'=>true));
$writer->writeToFile('xlsx-advanced.xlsx');

View File

@ -0,0 +1,20 @@
<?php
set_include_path( get_include_path().PATH_SEPARATOR."..");
include_once("xlsxwriter.class.php");
$chars = 'abcdefgh';
$header = array('col-string'=>'string','col-numbers'=>'integer','col-timestamps'=>'datetime');
$writer = new XLSXWriter();
$writer->writeSheetHeader('Sheet1', $header, ['auto_filter'=>true, 'widths'=>[15,15,30]] );
for($i=0; $i<1000; $i++)
{
$writer->writeSheetRow('Sheet1', array(
str_shuffle($chars),
rand()%10000,
date('Y-m-d H:i:s',time()-(rand()%31536000))
));
}
$writer->writeToFile('xlsx-autofilter.xlsx');
echo '#'.floor((memory_get_peak_usage())/1024/1024)."MB"."\n";

View File

@ -0,0 +1,22 @@
<?php
set_include_path( get_include_path().PATH_SEPARATOR."..");
include_once("xlsxwriter.class.php");
$chars = 'abcdefgh';
$header = array('c1'=>'string','c2'=>'integer','c3'=>'integer','c4'=>'integer','c5'=>'integer');
$writer = new XLSXWriter();
$writer->writeSheetHeader('Sheet1', $header, ['freeze_rows'=>1, 'freeze_columns'=>1] );
for($i=0; $i<250; $i++)
{
$writer->writeSheetRow('Sheet1', array(
str_shuffle($chars),
rand()%10000,
rand()%10000,
rand()%10000,
rand()%10000
));
}
$writer->writeToFile('xlsx-freeze-rows-columns.xlsx');
echo '#'.floor((memory_get_peak_usage())/1024/1024)."MB"."\n";

View File

@ -0,0 +1,19 @@
<?php
set_include_path( get_include_path().PATH_SEPARATOR."..");
include_once("xlsxwriter.class.php");
$header = array(
'c1-text'=>'string',//text
'c2-text'=>'@',//text
);
$rows = array(
array('abcdefg','hijklmnop'),
);
$writer = new XLSXWriter();
$writer->setRightToLeft(true);
$writer->writeSheetHeader('Sheet1', $header);
foreach($rows as $row)
$writer->writeSheetRow('Sheet1', $row);
$writer->writeToFile('xlsx-right-to-left.xlsx');

View File

@ -0,0 +1,15 @@
<?php
set_include_path( get_include_path().PATH_SEPARATOR."..");
include_once("xlsxwriter.class.php");
$rows = array(
array("not clickable","also not clickable",'=HYPERLINK("http://github.com", "Click for Github.com")'),
);
$writer = new XLSXWriter();
foreach($rows as $row)
$writer->writeSheetRow('Sheet1', $row);
$writer->writeToFile('xlsx-hyperlink.xlsx');
//$writer->writeToStdOut();
//echo $writer->writeToString();

View File

@ -0,0 +1,14 @@
README
------
run_test_and_diff.sh
Just a quick tool for diffing spreadsheets, from a baseline openoffice/libreoffice spreadsheet.
Requires xmllint and meld as command line tools in linux. The idea is you can manipulate the
xlsx spreadsheet and then see what the resulting xml is, and diff it with your test.xlsx
```sudo apt-get install xmllint libxml2-utils```
xlsxwriter.class.Test.php
A simple PHPUnit test for a basic spreadsheet

View File

@ -0,0 +1,11 @@
#!/bin/bash
if [ ! -f "$1" ] || [ ! -f "$2" ]; then
echo "Example Usage: $0 f1.xlsx f2.xlsx";
exit
fi
./extract.sh $1
./extract.sh $2
echo "Now, run this command:"
echo " meld openoffice/ test/";
#export DISPLAY=:0 && meld openoffice/ test/;

View File

@ -0,0 +1,36 @@
#!/bin/bash
FILENAME=`basename --suffix=.xlsx $1`
DIRNAME=$FILENAME"_dir"
if [ "" == "$1" ]; then
echo "Example Usage: $0 spreadsheet.xlsx";
exit
fi
if [ ! -f "$1" ]; then
echo "Example Usage: $0 spreadsheet.xlsx";
exit
fi
mkdir -p $DIRNAME;
cp $1 $DIRNAME;
cd $DIRNAME;
unzip -o $1;
for FILE in *.xml;
do
xmllint --format "$FILE" > temp.xml;
mv temp.xml $FILE;
done;
for FILE in */*.xml
do
xmllint --format "$FILE" > temp.xml;
mv temp.xml $FILE;
done;
for FILE in */*/*.xml
do
xmllint --format "$FILE" > temp.xml;
mv temp.xml $FILE;
done;
xmllint --format "xl/_rels/workbook.xml.rels" > temp.xml;
mv temp.xml xl/_rels/workbook.xml.rels;
cd ..;
exit

Binary file not shown.

View File

@ -0,0 +1,84 @@
<?php
include_once("../../xlsxwriter.class.php");
$writer = new XLSXWriter();
$keywords = array('some','interesting','keywords');
$writer->setTitle('Some Title');
$writer->setSubject('Some Subject');
$writer->setAuthor('Some Author');
$writer->setCompany('Some Company');
$writer->setKeywords($keywords);
$writer->setDescription('Some interesting description');
$header = array(
'General'=>'string',
'Simple Integer'=>'0',
'2 Decimal Places Integer'=>'0.00',
'Integer 1000s Group'=>'#,##0',
'1000s,Decimal,Leading Zero'=>'#,##0.00',
'1000s,Decimal,No Leading Zero'=>'#,###.00',
'Negative In Parentheses'=>'#,##0_);(#,##0)',
'Negative In Parentheses With Decimal'=>'#,##0.00_);(#,##0.00)',
);
$row = array('1000','2000','3000','4000','0.50','0.50','-50','-50');
$writer->writeSheet(array( $row ),'Number',$header);
$header = array(
'Whole Percent'=>'0%',
'Decimal Percent'=>'0.00%',
);
$row = array('1','1');
$writer->writeSheet(array( $row ),'Percent',$header);
$header = array(
'USD'=>'[$$-409]#,##0.00;[RED]-[$$-409]#,##0.00',
'CAD'=>'[$$-1009]#,##0.00;[RED]-[$$-1009]#,##0.00',
'Euro'=>'#,##0.00 [$€-407];[RED]-#,##0.00 [$€-407]',
'JPY'=>'[$¥-411]#,##0;[RED]-[$¥-411]#,##0',
'CNY'=>'[$¥-804]#,##0.00;[RED]-[$¥-804]#,##0.00',
);
$row = array('1000','2000','3000','4000','5000');
$writer->writeSheet(array( $row ) ,'Currency',$header);
$header = array(
'M/D/YY'=>'M/D/YY',
'MM/DD/YYYY'=>'MM/DD/YYYY',
'YYYY-MM-DD'=>'YYYY-MM-DD',
'YYYY-MM-DD HH:MM:SS'=>'YYYY-MM-DD HH:MM:SS',
'NN'=>'NN',
'NNN'=>'NNN',
'NNNN'=>'NNNN',
'D'=>'D',
'DD'=>'DD',
'M'=>'M',
'MM'=>'MM',
'MMM'=>'MMM',
'MMMM'=>'MMMM',
'YY'=>'YY',
'YYYY'=>'YYYY',
'Q YY'=>'Q YY',
'Q YYYY'=>'Q YYYY',
);
$row = array('1999-01-01','1999-01-01','1999-12-31','1999-12-31 00:00:00',
'1999-12-31','1999-12-31','1999-12-31',
'1999-12-31','1999-12-31','1999-12-31',
'1999-12-31','1999-12-31','1999-12-31',
'1999-12-31','1999-12-31','1999-12-31',
'1999-12-31');
$writer->writeSheet(array( $row ) ,'Date',$header);
$header = array(
'HH:MM'=>'HH:MM',
'HH:MM:SS'=>'HH:MM:SS',
'HH:MM AM/PM'=>'HH:MM AM/PM',
'HH:MM:SS AM/PM'=>'HH:MM:SS AM/PM',
);
$row = array('12-31-1999 01:23:00','12-31-1999 01:23:00','12-31-1999 01:23:00','12-31-1999 01:23:00');
$writer->writeSheet(array( $row ) ,'Time',$header);
$writer->writeToFile('formats.xlsx');

View File

@ -0,0 +1,84 @@
<?php
include_once("../../xlsxwriter.class.php");
$writer = new XLSXWriter();
$keywords = array('some','interesting','keywords');
$writer->setTitle('Some Title');
$writer->setSubject('Some Subject');
$writer->setAuthor('Some Author');
$writer->setCompany('Some Company');
$writer->setKeywords($keywords);
$writer->setDescription('Some interesting description');
$header = array(
'General'=>'string',
'Simple Integer'=>'0',
'2 Decimal Places Integer'=>'0.00',
'Integer 1000s Group'=>'#,##0',
'1000s,Decimal,Leading Zero'=>'#,##0.00',
'1000s,Decimal,No Leading Zero'=>'#,###.00',
'Negative In Parentheses'=>'#,##0_);(#,##0)',
'Negative In Parentheses With Decimal'=>'#,##0.00_);(#,##0.00)',
);
$row = array('1000','2000','3000','4000','0.50','0.50','-50','-50');
$writer->writeSheet(array( $row ),'Number',$header);
$header = array(
'Whole Percent'=>'0%',
'Decimal Percent'=>'0.00%',
);
$row = array('1','1');
$writer->writeSheet(array( $row ),'Percent',$header);
$header = array(
'USD'=>'[$$-409]#,##0.00;[RED]-[$$-409]#,##0.00',
'CAD'=>'[$$-1009]#,##0.00;[RED]-[$$-1009]#,##0.00',
'Euro'=>'#,##0.00 [$€-407];[RED]-#,##0.00 [$€-407]',
'JPY'=>'[$¥-411]#,##0;[RED]-[$¥-411]#,##0',
'CNY'=>'[$¥-804]#,##0.00;[RED]-[$¥-804]#,##0.00',
);
$row = array('1000','2000','3000','4000','5000');
$writer->writeSheet(array( $row ) ,'Currency',$header);
$header = array(
'M/D/YY'=>'M/D/YY',
'MM/DD/YYYY'=>'MM/DD/YYYY',
'YYYY-MM-DD'=>'YYYY-MM-DD',
'YYYY-MM-DD HH:MM:SS'=>'YYYY-MM-DD HH:MM:SS',
'NN'=>'NN',
'NNN'=>'NNN',
'NNNN'=>'NNNN',
'D'=>'D',
'DD'=>'DD',
'M'=>'M',
'MM'=>'MM',
'MMM'=>'MMM',
'MMMM'=>'MMMM',
'YY'=>'YY',
'YYYY'=>'YYYY',
'Q YY'=>'Q YY',
'Q YYYY'=>'Q YYYY',
);
$row = array('1999-01-01','1999-01-01','1999-12-31','1999-12-31 00:00:00',
'1999-12-31','1999-12-31','1999-12-31',
'1999-12-31','1999-12-31','1999-12-31',
'1999-12-31','1999-12-31','1999-12-31',
'1999-12-31','1999-12-31','1999-12-31',
'1999-12-31');
$writer->writeSheet(array( $row ) ,'Date',$header);
$header = array(
'HH:MM'=>'HH:MM',
'HH:MM:SS'=>'HH:MM:SS',
'HH:MM AM/PM'=>'HH:MM AM/PM',
'HH:MM:SS AM/PM'=>'HH:MM:SS AM/PM',
);
$row = array('12-31-1999 01:23:00','12-31-1999 01:23:00','12-31-1999 01:23:00','12-31-1999 01:23:00');
$writer->writeSheet(array( $row ) ,'Time',$header);
$writer->writeToFile('formats_.xlsx');

View File

@ -0,0 +1,33 @@
<?php
include_once("../xlsxwriter.class.php");
$header = array(
'year'=>'string',
'month'=>'string',
'amount'=>'money',
'first_event'=>'datetime',
'second_event'=>'date',
);
$data1 = array(
array('2003','1','-50.5','2010-01-01 23:00:00','2012-12-31 23:00:00'),
array('2003','=B2', '23.5','2010-01-01 00:00:00','2012-12-31 00:00:00'),
);
$data2 = array(
array('2003','01','343.12'),
array('2003','02','345.12'),
);
$writer = new XLSXWriter();
$keywords = array('some','interesting','keywords');
$writer->setTitle('Some Title');
$writer->setSubject('Some Subject');
$writer->setAuthor('Some Author');
$writer->setCompany('Some Company');
$writer->setKeywords($keywords);
$writer->setDescription('Some interesting description');
$writer->writeSheet($data1,'Sheet1',$header);
$writer->writeSheet($data2,'Sheet2');
$writer->writeToFile('test.xlsx');

Binary file not shown.

View File

@ -0,0 +1,124 @@
<?php
include_once __DIR__.'/../vendor/autoload.php';
//TODO test double:writeSheetHeader
//TODO test invalid UTF8
//TODO test outoforder writeSheetRow('Sheet1',());
class _XLSXWriter_ extends XLSXWriter
{
public function writeCell(XLSXWriter_BuffererWriter &$file, $row_number, $column_number, $value, $cell_format) {
return call_user_func_array('parent::writeCell', func_get_args());
}
}
//Just a simple test, by no means comprehensive
class XLSXWriterTest extends PHPUnit_Framework_TestCase
{
/**
* @covers XLSXWriter::writeCell
*/
public function testWriteCell()
{
$filename = tempnam("/tmp", "xlsx_writer");
$file_writer = new XLSXWriter_BuffererWriter($filename);
$xlsx_writer = new _XLSXWriter_();
$xlsx_writer->writeCell($file_writer, 0, 0, '0123', 'string');
$file_writer->close();
$cell_xml = file_get_contents($filename);
$this->assertNotEquals('<c r="A1" s="0" t="n"><v>123</v></c>', $cell_xml);
$this->assertEquals('<c r="A1" s="0" t="s"><v>0</v></c>', $cell_xml);//0123 should be the 0th index of the shared string array
@unlink($filename);
}
/**
* @covers XLSXWriter::writeToFile
*/
public function testWriteToFile()
{
$filename = tempnam("/tmp", "xlsx_writer");
$header = array('0'=>'string','1'=>'string','2'=>'string','3'=>'string');
$sheet = array(
array('55','66','77','88'),
array('10','11','12','13'),
);
$xlsx_writer = new XLSXWriter();
$xlsx_writer->writeSheet($sheet,'mysheet',$header);
$xlsx_writer->writeToFile($filename);
$zip = new ZipArchive();
$r = $zip->open($filename);
$this->assertTrue($r);
$r = $zip->numFiles>0 ? true : false;
$this->assertTrue($r);
$out_sheet = array();
for($z=0; $z<$zip->numFiles; $z++)
{
$inside_zip_filename = $zip->getNameIndex($z);
if (preg_match("/sheet(\d+).xml/", basename($inside_zip_filename)))
{
$out_sheet = $this->stripCellsFromSheetXML($zip->getFromName($inside_zip_filename));
array_shift($out_sheet);
$out_sheet = array_values($out_sheet);
}
}
$zip->close();
@unlink($filename);
$r1 = self::array_diff_assoc_recursive($out_sheet, $sheet);
$r2 = self::array_diff_assoc_recursive($sheet, $out_sheet);
$this->assertEmpty($r1);
$this->assertEmpty($r2);
}
private function stripCellsFromSheetXML($sheet_xml)
{
$output=array();
$xml = new SimpleXMLElement($sheet_xml);
$i=0;
foreach($xml->sheetData->row as $row)
{
$j=0;
foreach($row->c as $c)
{
$output[$i][$j] = (string)$c->v;
$j++;
}
$i++;
}
return $output;
}
public static function array_diff_assoc_recursive($array1, $array2)
{
foreach($array1 as $key => $value)
{
if(is_array($value))
{
if(!isset($array2[$key]) || !is_array($array2[$key]))
{
$difference[$key] = $value;
}
else
{
$new_diff = self::array_diff_assoc_recursive($value, $array2[$key]);
if(!empty($new_diff))
{
$difference[$key] = $new_diff;
}
}
}
else if(!isset($array2[$key]) || $array2[$key] != $value)
{
$difference[$key] = $value;
}
}
return !isset($difference) ? array() : $difference;
}
}

View File

@ -0,0 +1,980 @@
<?php
/*
* @license MIT License
* */
class XLSXWriter
{
//http://www.ecma-international.org/publications/standards/Ecma-376.htm
//http://officeopenxml.com/SSstyles.php
//------------------------------------------------------------------
//http://office.microsoft.com/en-us/excel-help/excel-specifications-and-limits-HP010073849.aspx
const EXCEL_2007_MAX_ROW=1048576;
const EXCEL_2007_MAX_COL=16384;
//------------------------------------------------------------------
protected $title;
protected $subject;
protected $author;
protected $isRightToLeft;
protected $company;
protected $description;
protected $keywords = array();
protected $tempdir;
protected $current_sheet;
protected $sheets = array();
protected $temp_files = array();
protected $cell_styles = array();
protected $number_formats = array();
public function __construct()
{
defined('ENT_XML1') or define('ENT_XML1',16);//for php 5.3, avoid fatal error
date_default_timezone_get() or date_default_timezone_set('UTC');//php.ini missing tz, avoid warning
is_writeable($this->tempFilename()) or self::log("Warning: tempdir ".sys_get_temp_dir()." not writeable, use ->setTempDir()");
class_exists('ZipArchive') or self::log("Error: ZipArchive class does not exist");
$this->addCellStyle($number_format='GENERAL', $style_string=null);
}
public function setTitle($title='') { $this->title=$title; }
public function setSubject($subject='') { $this->subject=$subject; }
public function setAuthor($author='') { $this->author=$author; }
public function setCompany($company='') { $this->company=$company; }
public function setKeywords($keywords='') { $this->keywords=$keywords; }
public function setDescription($description='') { $this->description=$description; }
public function setTempDir($tempdir='') { $this->tempdir=$tempdir; }
public function setRightToLeft($isRightToLeft=false){ $this->isRightToLeft=$isRightToLeft; }
public function __destruct()
{
if (!empty($this->temp_files)) {
foreach($this->temp_files as $temp_file) {
@unlink($temp_file);
}
}
}
protected function tempFilename()
{
$tempdir = !empty($this->tempdir) ? $this->tempdir : sys_get_temp_dir();
$filename = tempnam($tempdir, "xlsx_writer_");
if (!$filename) {
// If you are seeing this error, it's possible you may have too many open
// file handles. If you're creating a spreadsheet with many small inserts,
// it is possible to exceed the default 1024 open file handles. Run 'ulimit -a'
// and try increasing the 'open files' number with 'ulimit -n 8192'
throw new \Exception("Unable to create tempfile - check file handle limits?");
}
$this->temp_files[] = $filename;
return $filename;
}
public function writeToStdOut()
{
$temp_file = $this->tempFilename();
self::writeToFile($temp_file);
readfile($temp_file);
}
public function writeToString()
{
$temp_file = $this->tempFilename();
self::writeToFile($temp_file);
$string = file_get_contents($temp_file);
return $string;
}
public function writeToFile($filename)
{
foreach($this->sheets as $sheet_name => $sheet) {
self::finalizeSheet($sheet_name);//making sure all footers have been written
}
if ( file_exists( $filename ) ) {
if ( is_writable( $filename ) ) {
@unlink( $filename ); //if the zip already exists, remove it
} else {
self::log( "Error in " . __CLASS__ . "::" . __FUNCTION__ . ", file is not writeable." );
return;
}
}
$zip = new ZipArchive();
if (empty($this->sheets)) { self::log("Error in ".__CLASS__."::".__FUNCTION__.", no worksheets defined."); return; }
if (!$zip->open($filename, ZipArchive::CREATE)) { self::log("Error in ".__CLASS__."::".__FUNCTION__.", unable to create zip."); return; }
$zip->addEmptyDir("docProps/");
$zip->addFromString("docProps/app.xml" , self::buildAppXML() );
$zip->addFromString("docProps/core.xml", self::buildCoreXML());
$zip->addEmptyDir("_rels/");
$zip->addFromString("_rels/.rels", self::buildRelationshipsXML());
$zip->addEmptyDir("xl/worksheets/");
foreach($this->sheets as $sheet) {
$zip->addFile($sheet->filename, "xl/worksheets/".$sheet->xmlname );
}
$zip->addFromString("xl/workbook.xml" , self::buildWorkbookXML() );
$zip->addFile($this->writeStylesXML(), "xl/styles.xml" ); //$zip->addFromString("xl/styles.xml" , self::buildStylesXML() );
$zip->addFromString("[Content_Types].xml" , self::buildContentTypesXML() );
$zip->addEmptyDir("xl/_rels/");
$zip->addFromString("xl/_rels/workbook.xml.rels", self::buildWorkbookRelsXML() );
$zip->close();
}
protected function initializeSheet($sheet_name, $col_widths=array(), $auto_filter=false, $freeze_rows=false, $freeze_columns=false )
{
//if already initialized
if ($this->current_sheet==$sheet_name || isset($this->sheets[$sheet_name]))
return;
$sheet_filename = $this->tempFilename();
$sheet_xmlname = 'sheet' . (count($this->sheets) + 1).".xml";
$this->sheets[$sheet_name] = (object)array(
'filename' => $sheet_filename,
'sheetname' => $sheet_name,
'xmlname' => $sheet_xmlname,
'row_count' => 0,
'file_writer' => new XLSXWriter_BuffererWriter($sheet_filename),
'columns' => array(),
'merge_cells' => array(),
'max_cell_tag_start' => 0,
'max_cell_tag_end' => 0,
'auto_filter' => $auto_filter,
'freeze_rows' => $freeze_rows,
'freeze_columns' => $freeze_columns,
'finalized' => false,
);
$rightToLeftValue = $this->isRightToLeft ? 'true' : 'false';
$sheet = &$this->sheets[$sheet_name];
$tabselected = count($this->sheets) == 1 ? 'true' : 'false';//only first sheet is selected
$max_cell=XLSXWriter::xlsCell(self::EXCEL_2007_MAX_ROW, self::EXCEL_2007_MAX_COL);//XFE1048577
$sheet->file_writer->write('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' . "\n");
$sheet->file_writer->write('<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">');
$sheet->file_writer->write( '<sheetPr filterMode="false">');
$sheet->file_writer->write( '<pageSetUpPr fitToPage="false"/>');
$sheet->file_writer->write( '</sheetPr>');
$sheet->max_cell_tag_start = $sheet->file_writer->ftell();
$sheet->file_writer->write('<dimension ref="A1:' . $max_cell . '"/>');
$sheet->max_cell_tag_end = $sheet->file_writer->ftell();
$sheet->file_writer->write( '<sheetViews>');
$sheet->file_writer->write( '<sheetView colorId="64" defaultGridColor="true" rightToLeft="'.$rightToLeftValue.'" showFormulas="false" showGridLines="true" showOutlineSymbols="true" showRowColHeaders="true" showZeros="true" tabSelected="' . $tabselected . '" topLeftCell="A1" view="normal" windowProtection="false" workbookViewId="0" zoomScale="100" zoomScaleNormal="100" zoomScalePageLayoutView="100">');
if ($sheet->freeze_rows && $sheet->freeze_columns) {
$sheet->file_writer->write( '<pane ySplit="'.$sheet->freeze_rows.'" xSplit="'.$sheet->freeze_columns.'" topLeftCell="'.self::xlsCell($sheet->freeze_rows, $sheet->freeze_columns).'" activePane="bottomRight" state="frozen"/>');
$sheet->file_writer->write( '<selection activeCell="'.self::xlsCell($sheet->freeze_rows, 0).'" activeCellId="0" pane="topRight" sqref="'.self::xlsCell($sheet->freeze_rows, 0).'"/>');
$sheet->file_writer->write( '<selection activeCell="'.self::xlsCell(0, $sheet->freeze_columns).'" activeCellId="0" pane="bottomLeft" sqref="'.self::xlsCell(0, $sheet->freeze_columns).'"/>');
$sheet->file_writer->write( '<selection activeCell="'.self::xlsCell($sheet->freeze_rows, $sheet->freeze_columns).'" activeCellId="0" pane="bottomRight" sqref="'.self::xlsCell($sheet->freeze_rows, $sheet->freeze_columns).'"/>');
}
elseif ($sheet->freeze_rows) {
$sheet->file_writer->write( '<pane ySplit="'.$sheet->freeze_rows.'" topLeftCell="'.self::xlsCell($sheet->freeze_rows, 0).'" activePane="bottomLeft" state="frozen"/>');
$sheet->file_writer->write( '<selection activeCell="'.self::xlsCell($sheet->freeze_rows, 0).'" activeCellId="0" pane="bottomLeft" sqref="'.self::xlsCell($sheet->freeze_rows, 0).'"/>');
}
elseif ($sheet->freeze_columns) {
$sheet->file_writer->write( '<pane xSplit="'.$sheet->freeze_columns.'" topLeftCell="'.self::xlsCell(0, $sheet->freeze_columns).'" activePane="topRight" state="frozen"/>');
$sheet->file_writer->write( '<selection activeCell="'.self::xlsCell(0, $sheet->freeze_columns).'" activeCellId="0" pane="topRight" sqref="'.self::xlsCell(0, $sheet->freeze_columns).'"/>');
}
else { // not frozen
$sheet->file_writer->write( '<selection activeCell="A1" activeCellId="0" pane="topLeft" sqref="A1"/>');
}
$sheet->file_writer->write( '</sheetView>');
$sheet->file_writer->write( '</sheetViews>');
$sheet->file_writer->write( '<cols>');
$i=0;
if (!empty($col_widths)) {
foreach($col_widths as $column_width) {
$sheet->file_writer->write( '<col collapsed="false" hidden="false" max="'.($i+1).'" min="'.($i+1).'" style="0" customWidth="true" width="'.floatval($column_width).'"/>');
$i++;
}
}
$sheet->file_writer->write( '<col collapsed="false" hidden="false" max="1024" min="'.($i+1).'" style="0" customWidth="false" width="11.5"/>');
$sheet->file_writer->write( '</cols>');
$sheet->file_writer->write( '<sheetData>');
}
private function addCellStyle($number_format, $cell_style_string)
{
$number_format_idx = self::add_to_list_get_index($this->number_formats, $number_format);
$lookup_string = $number_format_idx.";".$cell_style_string;
$cell_style_idx = self::add_to_list_get_index($this->cell_styles, $lookup_string);
return $cell_style_idx;
}
private function initializeColumnTypes($header_types)
{
$column_types = array();
foreach($header_types as $v)
{
$number_format = self::numberFormatStandardized($v);
$number_format_type = self::determineNumberFormatType($number_format);
$cell_style_idx = $this->addCellStyle($number_format, $style_string=null);
$column_types[] = array('number_format' => $number_format,//contains excel format like 'YYYY-MM-DD HH:MM:SS'
'number_format_type' => $number_format_type, //contains friendly format like 'datetime'
'default_cell_style' => $cell_style_idx,
);
}
return $column_types;
}
public function writeSheetHeader($sheet_name, array $header_types, $col_options = null)
{
if (empty($sheet_name) || empty($header_types))
return;
$suppress_row = isset($col_options['suppress_row']) ? intval($col_options['suppress_row']) : false;
if (is_bool($col_options))
{
self::log( "Warning! passing $suppress_row=false|true to writeSheetHeader() is deprecated, this will be removed in a future version." );
$suppress_row = intval($col_options);
}
$style = &$col_options;
$col_widths = isset($col_options['widths']) ? (array)$col_options['widths'] : array();
$auto_filter = isset($col_options['auto_filter']) ? intval($col_options['auto_filter']) : false;
$freeze_rows = isset($col_options['freeze_rows']) ? intval($col_options['freeze_rows']) : false;
$freeze_columns = isset($col_options['freeze_columns']) ? intval($col_options['freeze_columns']) : false;
self::initializeSheet($sheet_name, $col_widths, $auto_filter, $freeze_rows, $freeze_columns);
$sheet = &$this->sheets[$sheet_name];
$sheet->columns = $this->initializeColumnTypes($header_types);
if (!$suppress_row)
{
$header_row = array_keys($header_types);
$sheet->file_writer->write('<row collapsed="false" customFormat="false" customHeight="false" hidden="false" ht="12.1" outlineLevel="0" r="' . ($sheet->row_count+1) . '">');
foreach ($header_row as $c => $v) {
$cell_style_idx = empty($style) ? $sheet->columns[$c]['default_cell_style'] : $this->addCellStyle( 'GENERAL', json_encode(isset($style[0]) ? $style[$c] : $style) );
$this->writeCell($sheet->file_writer, $sheet->row_count, $c, $v, $number_format_type='n_string', $cell_style_idx);
}
$sheet->file_writer->write('</row>');
$sheet->row_count++;
}
$this->current_sheet = $sheet_name;
}
public function writeSheetRow($sheet_name, array $row, $row_options=null)
{
if (empty($sheet_name))
return;
$this->initializeSheet($sheet_name);
$sheet = &$this->sheets[$sheet_name];
if (count($sheet->columns) < count($row)) {
$default_column_types = $this->initializeColumnTypes( array_fill($from=0, $until=count($row), 'GENERAL') );//will map to n_auto
$sheet->columns = array_merge((array)$sheet->columns, $default_column_types);
}
if (!empty($row_options))
{
$ht = isset($row_options['height']) ? floatval($row_options['height']) : 12.1;
$customHt = isset($row_options['height']) ? true : false;
$hidden = isset($row_options['hidden']) ? (bool)($row_options['hidden']) : false;
$collapsed = isset($row_options['collapsed']) ? (bool)($row_options['collapsed']) : false;
$sheet->file_writer->write('<row collapsed="'.($collapsed ? 'true' : 'false').'" customFormat="false" customHeight="'.($customHt ? 'true' : 'false').'" hidden="'.($hidden ? 'true' : 'false').'" ht="'.($ht).'" outlineLevel="0" r="' . ($sheet->row_count + 1) . '">');
}
else
{
$sheet->file_writer->write('<row collapsed="false" customFormat="false" customHeight="false" hidden="false" ht="12.1" outlineLevel="0" r="' . ($sheet->row_count + 1) . '">');
}
$style = &$row_options;
$c=0;
foreach ($row as $v) {
$number_format = $sheet->columns[$c]['number_format'];
$number_format_type = $sheet->columns[$c]['number_format_type'];
$cell_style_idx = empty($style) ? $sheet->columns[$c]['default_cell_style'] : $this->addCellStyle( $number_format, json_encode(isset($style[0]) ? $style[$c] : $style) );
$this->writeCell($sheet->file_writer, $sheet->row_count, $c, $v, $number_format_type, $cell_style_idx);
$c++;
}
$sheet->file_writer->write('</row>');
$sheet->row_count++;
$this->current_sheet = $sheet_name;
}
public function countSheetRows($sheet_name = '')
{
$sheet_name = $sheet_name ? $sheet_name : $this->current_sheet;
return array_key_exists($sheet_name, $this->sheets) ? $this->sheets[$sheet_name]->row_count : 0;
}
protected function finalizeSheet($sheet_name)
{
if (empty($sheet_name) || $this->sheets[$sheet_name]->finalized)
return;
$sheet = &$this->sheets[$sheet_name];
$sheet->file_writer->write( '</sheetData>');
if (!empty($sheet->merge_cells)) {
$sheet->file_writer->write( '<mergeCells>');
foreach ($sheet->merge_cells as $range) {
$sheet->file_writer->write( '<mergeCell ref="' . $range . '"/>');
}
$sheet->file_writer->write( '</mergeCells>');
}
$max_cell = self::xlsCell($sheet->row_count - 1, count($sheet->columns) - 1);
if ($sheet->auto_filter) {
$sheet->file_writer->write( '<autoFilter ref="A1:' . $max_cell . '"/>');
}
$sheet->file_writer->write( '<printOptions headings="false" gridLines="false" gridLinesSet="true" horizontalCentered="false" verticalCentered="false"/>');
$sheet->file_writer->write( '<pageMargins left="0.5" right="0.5" top="1.0" bottom="1.0" header="0.5" footer="0.5"/>');
$sheet->file_writer->write( '<pageSetup blackAndWhite="false" cellComments="none" copies="1" draft="false" firstPageNumber="1" fitToHeight="1" fitToWidth="1" horizontalDpi="300" orientation="portrait" pageOrder="downThenOver" paperSize="1" scale="100" useFirstPageNumber="true" usePrinterDefaults="false" verticalDpi="300"/>');
$sheet->file_writer->write( '<headerFooter differentFirst="false" differentOddEven="false">');
$sheet->file_writer->write( '<oddHeader>&amp;C&amp;&quot;Times New Roman,Regular&quot;&amp;12&amp;A</oddHeader>');
$sheet->file_writer->write( '<oddFooter>&amp;C&amp;&quot;Times New Roman,Regular&quot;&amp;12Page &amp;P</oddFooter>');
$sheet->file_writer->write( '</headerFooter>');
$sheet->file_writer->write('</worksheet>');
$max_cell_tag = '<dimension ref="A1:' . $max_cell . '"/>';
$padding_length = $sheet->max_cell_tag_end - $sheet->max_cell_tag_start - strlen($max_cell_tag);
$sheet->file_writer->fseek($sheet->max_cell_tag_start);
$sheet->file_writer->write($max_cell_tag.str_repeat(" ", $padding_length));
$sheet->file_writer->close();
$sheet->finalized=true;
}
public function markMergedCell($sheet_name, $start_cell_row, $start_cell_column, $end_cell_row, $end_cell_column)
{
if (empty($sheet_name) || $this->sheets[$sheet_name]->finalized)
return;
self::initializeSheet($sheet_name);
$sheet = &$this->sheets[$sheet_name];
$startCell = self::xlsCell($start_cell_row, $start_cell_column);
$endCell = self::xlsCell($end_cell_row, $end_cell_column);
$sheet->merge_cells[] = $startCell . ":" . $endCell;
}
public function writeSheet(array $data, $sheet_name='', array $header_types=array())
{
$sheet_name = empty($sheet_name) ? 'Sheet1' : $sheet_name;
$data = empty($data) ? array(array('')) : $data;
if (!empty($header_types))
{
$this->writeSheetHeader($sheet_name, $header_types);
}
foreach($data as $i=>$row)
{
$this->writeSheetRow($sheet_name, $row);
}
$this->finalizeSheet($sheet_name);
}
protected function writeCell(XLSXWriter_BuffererWriter &$file, $row_number, $column_number, $value, $num_format_type, $cell_style_idx)
{
$cell_name = self::xlsCell($row_number, $column_number);
if (!is_scalar($value) || $value==='') { //objects, array, empty
$file->write('<c r="'.$cell_name.'" s="'.$cell_style_idx.'"/>');
} elseif (is_string($value) && $value[0]=='='){
$file->write('<c r="'.$cell_name.'" s="'.$cell_style_idx.'" t="s"><f>'.self::xmlspecialchars(ltrim($value, '=')).'</f></c>');
} elseif ($num_format_type=='n_date') {
$file->write('<c r="'.$cell_name.'" s="'.$cell_style_idx.'" t="n"><v>'.intval(self::convert_date_time($value)).'</v></c>');
} elseif ($num_format_type=='n_datetime') {
$file->write('<c r="'.$cell_name.'" s="'.$cell_style_idx.'" t="n"><v>'.self::convert_date_time($value).'</v></c>');
} elseif ($num_format_type=='n_numeric') {
$file->write('<c r="'.$cell_name.'" s="'.$cell_style_idx.'" t="n"><v>'.self::xmlspecialchars($value).'</v></c>');//int,float,currency
} elseif ($num_format_type=='n_string') {
$file->write('<c r="'.$cell_name.'" s="'.$cell_style_idx.'" t="inlineStr"><is><t>'.self::xmlspecialchars($value).'</t></is></c>');
} elseif ($num_format_type=='n_auto' || 1) { //auto-detect unknown column types
if (!is_string($value) || $value=='0' || ($value[0]!='0' && ctype_digit($value)) || preg_match("/^\-?(0|[1-9][0-9]*)(\.[0-9]+)?$/", $value)){
$file->write('<c r="'.$cell_name.'" s="'.$cell_style_idx.'" t="n"><v>'.self::xmlspecialchars($value).'</v></c>');//int,float,currency
} else { //implied: ($cell_format=='string')
$file->write('<c r="'.$cell_name.'" s="'.$cell_style_idx.'" t="inlineStr"><is><t>'.self::xmlspecialchars($value).'</t></is></c>');
}
}
}
protected function styleFontIndexes()
{
static $border_allowed = array('left','right','top','bottom');
static $border_style_allowed = array('thin','medium','thick','dashDot','dashDotDot','dashed','dotted','double','hair','mediumDashDot','mediumDashDotDot','mediumDashed','slantDashDot');
static $horizontal_allowed = array('general','left','right','justify','center');
static $vertical_allowed = array('bottom','center','distributed','top');
$default_font = array('size'=>'10','name'=>'Arial','family'=>'2');
$fills = array('','');//2 placeholders for static xml later
$fonts = array('','','','');//4 placeholders for static xml later
$borders = array('');//1 placeholder for static xml later
$style_indexes = array();
foreach($this->cell_styles as $i=>$cell_style_string)
{
$semi_colon_pos = strpos($cell_style_string,";");
$number_format_idx = substr($cell_style_string, 0, $semi_colon_pos);
$style_json_string = substr($cell_style_string, $semi_colon_pos+1);
$style = @json_decode($style_json_string, $as_assoc=true);
$style_indexes[$i] = array('num_fmt_idx'=>$number_format_idx);//initialize entry
if (isset($style['border']) && is_string($style['border']))//border is a comma delimited str
{
$border_value['side'] = array_intersect(explode(",", $style['border']), $border_allowed);
if (isset($style['border-style']) && in_array($style['border-style'],$border_style_allowed))
{
$border_value['style'] = $style['border-style'];
}
if (isset($style['border-color']) && is_string($style['border-color']) && $style['border-color'][0]=='#')
{
$v = substr($style['border-color'],1,6);
$v = strlen($v)==3 ? $v[0].$v[0].$v[1].$v[1].$v[2].$v[2] : $v;// expand cf0 => ccff00
$border_value['color'] = "FF".strtoupper($v);
}
$style_indexes[$i]['border_idx'] = self::add_to_list_get_index($borders, json_encode($border_value));
}
if (isset($style['fill']) && is_string($style['fill']) && $style['fill'][0]=='#')
{
$v = substr($style['fill'],1,6);
$v = strlen($v)==3 ? $v[0].$v[0].$v[1].$v[1].$v[2].$v[2] : $v;// expand cf0 => ccff00
$style_indexes[$i]['fill_idx'] = self::add_to_list_get_index($fills, "FF".strtoupper($v) );
}
if (isset($style['halign']) && in_array($style['halign'],$horizontal_allowed))
{
$style_indexes[$i]['alignment'] = true;
$style_indexes[$i]['halign'] = $style['halign'];
}
if (isset($style['valign']) && in_array($style['valign'],$vertical_allowed))
{
$style_indexes[$i]['alignment'] = true;
$style_indexes[$i]['valign'] = $style['valign'];
}
if (isset($style['wrap_text']))
{
$style_indexes[$i]['alignment'] = true;
$style_indexes[$i]['wrap_text'] = (bool)$style['wrap_text'];
}
$font = $default_font;
if (isset($style['font-size']))
{
$font['size'] = floatval($style['font-size']);//floatval to allow "10.5" etc
}
if (isset($style['font']) && is_string($style['font']))
{
if ($style['font']=='Comic Sans MS') { $font['family']=4; }
if ($style['font']=='Times New Roman') { $font['family']=1; }
if ($style['font']=='Courier New') { $font['family']=3; }
$font['name'] = strval($style['font']);
}
if (isset($style['font-style']) && is_string($style['font-style']))
{
if (strpos($style['font-style'], 'bold')!==false) { $font['bold'] = true; }
if (strpos($style['font-style'], 'italic')!==false) { $font['italic'] = true; }
if (strpos($style['font-style'], 'strike')!==false) { $font['strike'] = true; }
if (strpos($style['font-style'], 'underline')!==false) { $font['underline'] = true; }
}
if (isset($style['color']) && is_string($style['color']) && $style['color'][0]=='#' )
{
$v = substr($style['color'],1,6);
$v = strlen($v)==3 ? $v[0].$v[0].$v[1].$v[1].$v[2].$v[2] : $v;// expand cf0 => ccff00
$font['color'] = "FF".strtoupper($v);
}
if ($font!=$default_font)
{
$style_indexes[$i]['font_idx'] = self::add_to_list_get_index($fonts, json_encode($font) );
}
}
return array('fills'=>$fills,'fonts'=>$fonts,'borders'=>$borders,'styles'=>$style_indexes );
}
protected function writeStylesXML()
{
$r = self::styleFontIndexes();
$fills = $r['fills'];
$fonts = $r['fonts'];
$borders = $r['borders'];
$style_indexes = $r['styles'];
$temporary_filename = $this->tempFilename();
$file = new XLSXWriter_BuffererWriter($temporary_filename);
$file->write('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'."\n");
$file->write('<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">');
$file->write('<numFmts count="'.count($this->number_formats).'">');
foreach($this->number_formats as $i=>$v) {
$file->write('<numFmt numFmtId="'.(164+$i).'" formatCode="'.self::xmlspecialchars($v).'" />');
}
//$file->write( '<numFmt formatCode="GENERAL" numFmtId="164"/>');
//$file->write( '<numFmt formatCode="[$$-1009]#,##0.00;[RED]\-[$$-1009]#,##0.00" numFmtId="165"/>');
//$file->write( '<numFmt formatCode="YYYY-MM-DD\ HH:MM:SS" numFmtId="166"/>');
//$file->write( '<numFmt formatCode="YYYY-MM-DD" numFmtId="167"/>');
$file->write('</numFmts>');
$file->write('<fonts count="'.(count($fonts)).'">');
$file->write( '<font><name val="Arial"/><charset val="1"/><family val="2"/><sz val="10"/></font>');
$file->write( '<font><name val="Arial"/><family val="0"/><sz val="10"/></font>');
$file->write( '<font><name val="Arial"/><family val="0"/><sz val="10"/></font>');
$file->write( '<font><name val="Arial"/><family val="0"/><sz val="10"/></font>');
foreach($fonts as $font) {
if (!empty($font)) { //fonts have 4 empty placeholders in array to offset the 4 static xml entries above
$f = json_decode($font,true);
$file->write('<font>');
$file->write( '<name val="'.htmlspecialchars($f['name']).'"/><charset val="1"/><family val="'.intval($f['family']).'"/>');
$file->write( '<sz val="'.intval($f['size']).'"/>');
if (!empty($f['color'])) { $file->write('<color rgb="'.strval($f['color']).'"/>'); }
if (!empty($f['bold'])) { $file->write('<b val="true"/>'); }
if (!empty($f['italic'])) { $file->write('<i val="true"/>'); }
if (!empty($f['underline'])) { $file->write('<u val="single"/>'); }
if (!empty($f['strike'])) { $file->write('<strike val="true"/>'); }
$file->write('</font>');
}
}
$file->write('</fonts>');
$file->write('<fills count="'.(count($fills)).'">');
$file->write( '<fill><patternFill patternType="none"/></fill>');
$file->write( '<fill><patternFill patternType="gray125"/></fill>');
foreach($fills as $fill) {
if (!empty($fill)) { //fills have 2 empty placeholders in array to offset the 2 static xml entries above
$file->write('<fill><patternFill patternType="solid"><fgColor rgb="'.strval($fill).'"/><bgColor indexed="64"/></patternFill></fill>');
}
}
$file->write('</fills>');
$file->write('<borders count="'.(count($borders)).'">');
$file->write( '<border diagonalDown="false" diagonalUp="false"><left/><right/><top/><bottom/><diagonal/></border>');
foreach($borders as $border) {
if (!empty($border)) { //fonts have an empty placeholder in the array to offset the static xml entry above
$pieces = json_decode($border,true);
$border_style = !empty($pieces['style']) ? $pieces['style'] : 'hair';
$border_color = !empty($pieces['color']) ? '<color rgb="'.strval($pieces['color']).'"/>' : '';
$file->write('<border diagonalDown="false" diagonalUp="false">');
foreach (array('left', 'right', 'top', 'bottom') as $side)
{
$show_side = in_array($side,$pieces['side']) ? true : false;
$file->write($show_side ? "<$side style=\"$border_style\">$border_color</$side>" : "<$side/>");
}
$file->write( '<diagonal/>');
$file->write('</border>');
}
}
$file->write('</borders>');
$file->write('<cellStyleXfs count="20">');
$file->write( '<xf applyAlignment="true" applyBorder="true" applyFont="true" applyProtection="true" borderId="0" fillId="0" fontId="0" numFmtId="164">');
$file->write( '<alignment horizontal="general" indent="0" shrinkToFit="false" textRotation="0" vertical="bottom" wrapText="false"/>');
$file->write( '<protection hidden="false" locked="true"/>');
$file->write( '</xf>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="1" numFmtId="0"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="1" numFmtId="0"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="2" numFmtId="0"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="2" numFmtId="0"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="1" numFmtId="43"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="1" numFmtId="41"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="1" numFmtId="44"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="1" numFmtId="42"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="1" numFmtId="9"/>');
$file->write('</cellStyleXfs>');
$file->write('<cellXfs count="'.(count($style_indexes)).'">');
//$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="false" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="164" xfId="0"/>');
//$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="false" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="165" xfId="0"/>');
//$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="false" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="166" xfId="0"/>');
//$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="false" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="167" xfId="0"/>');
foreach($style_indexes as $v)
{
$applyAlignment = isset($v['alignment']) ? 'true' : 'false';
$wrapText = !empty($v['wrap_text']) ? 'true' : 'false';
$horizAlignment = isset($v['halign']) ? $v['halign'] : 'general';
$vertAlignment = isset($v['valign']) ? $v['valign'] : 'bottom';
$applyBorder = isset($v['border_idx']) ? 'true' : 'false';
$applyFont = 'true';
$borderIdx = isset($v['border_idx']) ? intval($v['border_idx']) : 0;
$fillIdx = isset($v['fill_idx']) ? intval($v['fill_idx']) : 0;
$fontIdx = isset($v['font_idx']) ? intval($v['font_idx']) : 0;
//$file->write('<xf applyAlignment="'.$applyAlignment.'" applyBorder="'.$applyBorder.'" applyFont="'.$applyFont.'" applyProtection="false" borderId="'.($borderIdx).'" fillId="'.($fillIdx).'" fontId="'.($fontIdx).'" numFmtId="'.(164+$v['num_fmt_idx']).'" xfId="0"/>');
$file->write('<xf applyAlignment="'.$applyAlignment.'" applyBorder="'.$applyBorder.'" applyFont="'.$applyFont.'" applyProtection="false" borderId="'.($borderIdx).'" fillId="'.($fillIdx).'" fontId="'.($fontIdx).'" numFmtId="'.(164+$v['num_fmt_idx']).'" xfId="0">');
$file->write(' <alignment horizontal="'.$horizAlignment.'" vertical="'.$vertAlignment.'" textRotation="0" wrapText="'.$wrapText.'" indent="0" shrinkToFit="false"/>');
$file->write(' <protection locked="true" hidden="false"/>');
$file->write('</xf>');
}
$file->write('</cellXfs>');
$file->write( '<cellStyles count="6">');
$file->write( '<cellStyle builtinId="0" customBuiltin="false" name="Normal" xfId="0"/>');
$file->write( '<cellStyle builtinId="3" customBuiltin="false" name="Comma" xfId="15"/>');
$file->write( '<cellStyle builtinId="6" customBuiltin="false" name="Comma [0]" xfId="16"/>');
$file->write( '<cellStyle builtinId="4" customBuiltin="false" name="Currency" xfId="17"/>');
$file->write( '<cellStyle builtinId="7" customBuiltin="false" name="Currency [0]" xfId="18"/>');
$file->write( '<cellStyle builtinId="5" customBuiltin="false" name="Percent" xfId="19"/>');
$file->write( '</cellStyles>');
$file->write('</styleSheet>');
$file->close();
return $temporary_filename;
}
protected function buildAppXML()
{
$app_xml="";
$app_xml.='<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'."\n";
$app_xml.='<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes">';
$app_xml.='<TotalTime>0</TotalTime>';
$app_xml.='<Company>'.self::xmlspecialchars($this->company).'</Company>';
$app_xml.='</Properties>';
return $app_xml;
}
protected function buildCoreXML()
{
$core_xml="";
$core_xml.='<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'."\n";
$core_xml.='<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">';
$core_xml.='<dcterms:created xsi:type="dcterms:W3CDTF">'.date("Y-m-d\TH:i:s.00\Z").'</dcterms:created>';//$date_time = '2014-10-25T15:54:37.00Z';
$core_xml.='<dc:title>'.self::xmlspecialchars($this->title).'</dc:title>';
$core_xml.='<dc:subject>'.self::xmlspecialchars($this->subject).'</dc:subject>';
$core_xml.='<dc:creator>'.self::xmlspecialchars($this->author).'</dc:creator>';
if (!empty($this->keywords)) {
$core_xml.='<cp:keywords>'.self::xmlspecialchars(implode (", ", (array)$this->keywords)).'</cp:keywords>';
}
$core_xml.='<dc:description>'.self::xmlspecialchars($this->description).'</dc:description>';
$core_xml.='<cp:revision>0</cp:revision>';
$core_xml.='</cp:coreProperties>';
return $core_xml;
}
protected function buildRelationshipsXML()
{
$rels_xml="";
$rels_xml.='<?xml version="1.0" encoding="UTF-8"?>'."\n";
$rels_xml.='<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">';
$rels_xml.='<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>';
$rels_xml.='<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>';
$rels_xml.='<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>';
$rels_xml.="\n";
$rels_xml.='</Relationships>';
return $rels_xml;
}
protected function buildWorkbookXML()
{
$i=0;
$workbook_xml="";
$workbook_xml.='<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'."\n";
$workbook_xml.='<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">';
$workbook_xml.='<fileVersion appName="Calc"/><workbookPr backupFile="false" showObjects="all" date1904="false"/><workbookProtection/>';
$workbook_xml.='<bookViews><workbookView activeTab="0" firstSheet="0" showHorizontalScroll="true" showSheetTabs="true" showVerticalScroll="true" tabRatio="212" windowHeight="8192" windowWidth="16384" xWindow="0" yWindow="0"/></bookViews>';
$workbook_xml.='<sheets>';
foreach($this->sheets as $sheet_name=>$sheet) {
$sheetname = self::sanitize_sheetname($sheet->sheetname);
$workbook_xml.='<sheet name="'.self::xmlspecialchars($sheetname).'" sheetId="'.($i+1).'" state="visible" r:id="rId'.($i+2).'"/>';
$i++;
}
$workbook_xml.='</sheets>';
$workbook_xml.='<definedNames>';
foreach($this->sheets as $sheet_name=>$sheet) {
if ($sheet->auto_filter) {
$sheetname = self::sanitize_sheetname($sheet->sheetname);
$workbook_xml.='<definedName name="_xlnm._FilterDatabase" localSheetId="0" hidden="1">\''.self::xmlspecialchars($sheetname).'\'!$A$1:' . self::xlsCell($sheet->row_count - 1, count($sheet->columns) - 1, true) . '</definedName>';
$i++;
}
}
$workbook_xml.='</definedNames>';
$workbook_xml.='<calcPr iterateCount="100" refMode="A1" iterate="false" iterateDelta="0.001"/></workbook>';
return $workbook_xml;
}
protected function buildWorkbookRelsXML()
{
$i=0;
$wkbkrels_xml="";
$wkbkrels_xml.='<?xml version="1.0" encoding="UTF-8"?>'."\n";
$wkbkrels_xml.='<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">';
$wkbkrels_xml.='<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>';
foreach($this->sheets as $sheet_name=>$sheet) {
$wkbkrels_xml.='<Relationship Id="rId'.($i+2).'" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/'.($sheet->xmlname).'"/>';
$i++;
}
$wkbkrels_xml.="\n";
$wkbkrels_xml.='</Relationships>';
return $wkbkrels_xml;
}
protected function buildContentTypesXML()
{
$content_types_xml="";
$content_types_xml.='<?xml version="1.0" encoding="UTF-8"?>'."\n";
$content_types_xml.='<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">';
$content_types_xml.='<Override PartName="/_rels/.rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>';
$content_types_xml.='<Override PartName="/xl/_rels/workbook.xml.rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>';
foreach($this->sheets as $sheet_name=>$sheet) {
$content_types_xml.='<Override PartName="/xl/worksheets/'.($sheet->xmlname).'" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>';
}
$content_types_xml.='<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>';
$content_types_xml.='<Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>';
$content_types_xml.='<Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/>';
$content_types_xml.='<Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>';
$content_types_xml.="\n";
$content_types_xml.='</Types>';
return $content_types_xml;
}
//------------------------------------------------------------------
/*
* @param $row_number int, zero based
* @param $column_number int, zero based
* @param $absolute bool
* @return Cell label/coordinates, ex: A1, C3, AA42 (or if $absolute==true: $A$1, $C$3, $AA$42)
* */
public static function xlsCell($row_number, $column_number, $absolute=false)
{
$n = $column_number;
for($r = ""; $n >= 0; $n = intval($n / 26) - 1) {
$r = chr($n%26 + 0x41) . $r;
}
if ($absolute) {
return '$' . $r . '$' . ($row_number+1);
}
return $r . ($row_number+1);
}
//------------------------------------------------------------------
public static function log($string)
{
//file_put_contents("php://stderr", date("Y-m-d H:i:s:").rtrim(is_array($string) ? json_encode($string) : $string)."\n");
error_log(date("Y-m-d H:i:s:").rtrim(is_array($string) ? json_encode($string) : $string)."\n");
}
//------------------------------------------------------------------
public static function sanitize_filename($filename) //http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx
{
$nonprinting = array_map('chr', range(0,31));
$invalid_chars = array('<', '>', '?', '"', ':', '|', '\\', '/', '*', '&');
$all_invalids = array_merge($nonprinting,$invalid_chars);
return str_replace($all_invalids, "", $filename);
}
//------------------------------------------------------------------
public static function sanitize_sheetname($sheetname)
{
static $badchars = '\\/?*:[]';
static $goodchars = ' ';
$sheetname = strtr($sheetname, $badchars, $goodchars);
$sheetname = function_exists('mb_substr') ? mb_substr($sheetname, 0, 31) : substr($sheetname, 0, 31);
$sheetname = trim(trim(trim($sheetname),"'"));//trim before and after trimming single quotes
return !empty($sheetname) ? $sheetname : 'Sheet'.((rand()%900)+100);
}
//------------------------------------------------------------------
public static function xmlspecialchars($val)
{
//note, badchars does not include \t\n\r (\x09\x0a\x0d)
static $badchars = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0b\x0c\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x7f";
static $goodchars = " ";
return strtr(htmlspecialchars((string)$val, ENT_QUOTES | ENT_XML1 | ENT_SUBSTITUTE), $badchars, $goodchars);//strtr appears to be faster than str_replace
}
//------------------------------------------------------------------
public static function array_first_key(array $arr)
{
reset($arr);
$first_key = key($arr);
return $first_key;
}
//------------------------------------------------------------------
private static function determineNumberFormatType($num_format)
{
$num_format = preg_replace("/\[(Black|Blue|Cyan|Green|Magenta|Red|White|Yellow)\]/i", "", $num_format);
if ($num_format=='GENERAL') return 'n_auto';
if ($num_format=='@') return 'n_string';
if ($num_format=='0') return 'n_numeric';
if (preg_match('/[H]{1,2}:[M]{1,2}(?![^"]*+")/i', $num_format)) return 'n_datetime';
if (preg_match('/[M]{1,2}:[S]{1,2}(?![^"]*+")/i', $num_format)) return 'n_datetime';
if (preg_match('/[Y]{2,4}(?![^"]*+")/i', $num_format)) return 'n_date';
if (preg_match('/[D]{1,2}(?![^"]*+")/i', $num_format)) return 'n_date';
if (preg_match('/[M]{1,2}(?![^"]*+")/i', $num_format)) return 'n_date';
if (preg_match('/$(?![^"]*+")/', $num_format)) return 'n_numeric';
if (preg_match('/%(?![^"]*+")/', $num_format)) return 'n_numeric';
if (preg_match('/0(?![^"]*+")/', $num_format)) return 'n_numeric';
return 'n_auto';
}
//------------------------------------------------------------------
private static function numberFormatStandardized($num_format)
{
if ($num_format=='money') { $num_format='dollar'; }
if ($num_format=='number') { $num_format='integer'; }
if ($num_format=='string') $num_format='@';
else if ($num_format=='integer') $num_format='0';
else if ($num_format=='date') $num_format='YYYY-MM-DD';
else if ($num_format=='datetime') $num_format='YYYY-MM-DD HH:MM:SS';
else if ($num_format=='time') $num_format='HH:MM:SS';
else if ($num_format=='price') $num_format='#,##0.00';
else if ($num_format=='dollar') $num_format='[$$-1009]#,##0.00;[RED]-[$$-1009]#,##0.00';
else if ($num_format=='euro') $num_format='#,##0.00 [$€-407];[RED]-#,##0.00 [$€-407]';
$ignore_until='';
$escaped = '';
for($i=0,$ix=strlen($num_format); $i<$ix; $i++)
{
$c = $num_format[$i];
if ($ignore_until=='' && $c=='[')
$ignore_until=']';
else if ($ignore_until=='' && $c=='"')
$ignore_until='"';
else if ($ignore_until==$c)
$ignore_until='';
if ($ignore_until=='' && ($c==' ' || $c=='-' || $c=='(' || $c==')') && ($i==0 || $num_format[$i-1]!='_'))
$escaped.= "\\".$c;
else
$escaped.= $c;
}
return $escaped;
}
//------------------------------------------------------------------
public static function add_to_list_get_index(&$haystack, $needle)
{
$existing_idx = array_search($needle, $haystack, $strict=true);
if ($existing_idx===false)
{
$existing_idx = count($haystack);
$haystack[] = $needle;
}
return $existing_idx;
}
//------------------------------------------------------------------
public static function convert_date_time($date_input) //thanks to Excel::Writer::XLSX::Worksheet.pm (perl)
{
$days = 0; # Number of days since epoch
$seconds = 0; # Time expressed as fraction of 24h hours in seconds
$year=$month=$day=0;
$hour=$min =$sec=0;
$date_time = $date_input;
if (preg_match("/(\d{4})\-(\d{2})\-(\d{2})/", $date_time, $matches))
{
list($junk,$year,$month,$day) = $matches;
}
if (preg_match("/(\d+):(\d{2}):(\d{2})/", $date_time, $matches))
{
list($junk,$hour,$min,$sec) = $matches;
$seconds = ( $hour * 60 * 60 + $min * 60 + $sec ) / ( 24 * 60 * 60 );
}
//using 1900 as epoch, not 1904, ignoring 1904 special case
# Special cases for Excel.
if ("$year-$month-$day"=='1899-12-31') return $seconds ; # Excel 1900 epoch
if ("$year-$month-$day"=='1900-01-00') return $seconds ; # Excel 1900 epoch
if ("$year-$month-$day"=='1900-02-29') return 60 + $seconds ; # Excel false leapday
# We calculate the date by calculating the number of days since the epoch
# and adjust for the number of leap days. We calculate the number of leap
# days by normalising the year in relation to the epoch. Thus the year 2000
# becomes 100 for 4 and 100 year leapdays and 400 for 400 year leapdays.
$epoch = 1900;
$offset = 0;
$norm = 300;
$range = $year - $epoch;
# Set month days and check for leap year.
$leap = (($year % 400 == 0) || (($year % 4 == 0) && ($year % 100)) ) ? 1 : 0;
$mdays = array( 31, ($leap ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 );
# Some boundary checks
if ($year!=0 || $month !=0 || $day!=0)
{
if($year < $epoch || $year > 9999) return 0;
if($month < 1 || $month > 12) return 0;
if($day < 1 || $day > $mdays[ $month - 1 ]) return 0;
}
# Accumulate the number of days since the epoch.
$days = $day; # Add days for current month
$days += array_sum( array_slice($mdays, 0, $month-1 ) ); # Add days for past months
$days += $range * 365; # Add days for past years
$days += intval( ( $range ) / 4 ); # Add leapdays
$days -= intval( ( $range + $offset ) / 100 ); # Subtract 100 year leapdays
$days += intval( ( $range + $offset + $norm ) / 400 ); # Add 400 year leapdays
$days -= $leap; # Already counted above
# Adjust for Excel erroneously treating 1900 as a leap year.
if ($days > 59) { $days++;}
return $days + $seconds;
}
//------------------------------------------------------------------
}
class XLSXWriter_BuffererWriter
{
protected $fd=null;
protected $buffer='';
protected $check_utf8=false;
public function __construct($filename, $fd_fopen_flags='w', $check_utf8=false)
{
$this->check_utf8 = $check_utf8;
$this->fd = fopen($filename, $fd_fopen_flags);
if ($this->fd===false) {
XLSXWriter::log("Unable to open $filename for writing.");
}
}
public function write($string)
{
$this->buffer.=$string;
if (isset($this->buffer[8191])) {
$this->purge();
}
}
protected function purge()
{
if ($this->fd) {
if ($this->check_utf8 && !self::isValidUTF8($this->buffer)) {
XLSXWriter::log("Error, invalid UTF8 encoding detected.");
$this->check_utf8 = false;
}
fwrite($this->fd, $this->buffer);
$this->buffer='';
}
}
public function close()
{
$this->purge();
if ($this->fd) {
fclose($this->fd);
$this->fd=null;
}
}
public function __destruct()
{
$this->close();
}
public function ftell()
{
if ($this->fd) {
$this->purge();
return ftell($this->fd);
}
return -1;
}
public function fseek($pos)
{
if ($this->fd) {
$this->purge();
return fseek($this->fd, $pos);
}
return -1;
}
protected static function isValidUTF8($string)
{
if (function_exists('mb_check_encoding'))
{
return mb_check_encoding($string, 'UTF-8') ? true : false;
}
return preg_match("//u", $string) ? true : false;
}
}
// vim: set filetype=php expandtab tabstop=4 shiftwidth=4 autoindent smartindent:

View File

@ -1,5 +1,5 @@
<?php
// This file is automatically generated at:2022-04-24 10:25:12
// This file is automatically generated at:2023-09-28 14:28:35
declare (strict_types = 1);
return array (
0 => 'think\\captcha\\CaptchaService',

1
server/vendor/xin/container vendored Submodule

@ -0,0 +1 @@
Subproject commit 97bb67f87dd851545938a1f2fe0ffbd379e3ff81

1
server/vendor/xin/helper vendored Submodule

@ -0,0 +1 @@
Subproject commit 02a58132dae2aea2d1c0b8e66f55125969224747