Coder Social home page Coder Social logo

excel-merge's Introduction

Excel Merge

Merges two or more Excel files into one file, while keeping formatting, formulas, VBA code and conditional styling intact. This software works with Excel 2007 (.xlsx and .xlsm) files and can only generate Excel 2007 files as output. The older .xls format is unfortunately not supported, but you can work around that if necessary.

This is a software library that is designed to be used as part of a larger piece of software. It cannot be used as standalone software by itself.

Installation

With composer

php composer.phar require infostreams/excel-merge

Use

The most basic use of this software looks something like this

<?php
  require("vendor/autoload.php");

  $files = array("sheet_with_vba_code.xlsm", "generated_file.xlsx", "tmp/third_file.xlsx");
  
  $merged = new ExcelMerge\ExcelMerge($files);            
  $merged->download("my-filename.xlsm");
  
  // or
  
  $filename = $merged->save("my-directory/my-filename.xlsm");
?>

Raison d'être and use case

This library exists for one reason only: to work around the humongous memory requirements of the otherwise excellent PHPExcel library. I had to export the contents of a database as an Excel file with about 10 worksheets, some of them relatively large, and PHPExcel very quickly ran out of memory after producing about 2 or 3 of the required worksheets, even after increasing the PHP memory limit to 256 and then 512 Mb. I was not doing anything spectacular and am certainly not the only one to have run into this issue.

At this point I could have chosen a different Excel library to generate the export, and I did, but these would not allow me to use VBA code in my exported file, and would not recognize some of the Excel formulas I needed. PHPExcel would allow me to do these things, but ran out of memory because it insists on keeping a complete mental model of all the sheets in memory before it could produce an output file. That makes sense for PHPExcel but doesn't work for my use case.

Therefore, I decided to circumvent PHPExcel's memory limitations by using it to generate and then write all sheets as individual Excel files, and then write some code to merge these Excel files into one.

How it works

Instead of trying to keep a mental model of the whole Excel file in memory, this library simply operates directly on the XML files that are inside Excel2007 files. The library doesn't really understand these XML files, it just knows which files it needs to copy where and how to modify the XML in order to add one sheet of one Excel file to the other.

This means that the most memory it will ever use is directly related to how large your largest worksheet is.

Results

I had to generate an Excel file with 11 relatively sizable worksheets (two or three sheets with about 2000 rows). PHPExcel took over 30 minutes and over 512 Mb of memory to generate this, after which I aborted the process. With this library, I can generate the same export in 28.2 seconds with a peak memory use of 67 Mb.

Support for 'native' Excel files

I've tried merging files produced by Excel itself, but somehow it fails. I worked around it by loading the file with PHPExcel and writing it as a new Excel2007 file, and then merging that instead. If you figure out why it fails: pull requests welcome.

Support for .xls files and Libre/OpenOffice Calc and Gnumeric

You can merge .xls files, or any of the import formats supported by PHPExcel, by reading the file with PHPExcel and writing it as a temporary Excel2007 file. You then merge the temporary Excel2007 file instead of the original file

Requirements

This library uses DOMDocument and DOMXPath extensively. These are installed and available in PHP5 by default. If they aren't, check here.

Minimum PHP version is most likely v5.3.

excel-merge's People

Contributors

carolineclep avatar infostreams avatar mdanko2000 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

excel-merge's Issues

Support PHP 8.1

Hi everyone,

There a chance to make this package support php 8.1?

Add PR #13 to a new tag

Hi,

I've just discovered your lib after running into memory issues while merging XSLX files.

All works great ONLY with the modification done on PR #13 . However, this change is only available on your master branch. Could you create a tag with this modification to obtain a stable version via composer install ?

Cannot use object of type DOMNodeList as array

First off, thanks for the great library for merging excel. I'm currently using PHP 5.3.3 on a CentOS 6 box and I get a fatal error when trying to merge 2 excel files regarding using DOMNodeList as an array in the Tasks/Styles.php file.

If I change all $elems[0] to $elems->item(0), I no longer get a fatal error and the excel generates successfully. Could you review the fix and see if you can apply it to your Master release. I want to continue and use your repository.

Temporary folder not unique

Hi,

When merging several groups of small files one after the others it tries to create a temporary folder working_dir with an existing name based on date+hour+minute+second (not yet deleted?) so it crashes. It works better when adding uniqid() in the name.

Regards

Merged file is broken

Hello, I'm trying to merge a .xlsm and a .xlsx files together. The first one is my "template" file with only a couple of macros, the second one only have 3 lines to test. I'm unable to figure the issue. Maybe can you take a look?

Thanks in advance.

test.zip

Question - Merging sheet content with the same name

Hi,

I came across this tool when I was working with https://github.com/PHPOffice/PhpSpreadsheet on an excel macro enabled file. In my case I need to populate the macro sheet with data, but I found the macro logic is getting stripped out when I write to the file.

In my case, i have a .xlsm file with ten sheets which contains macro logic. I have a second file with ten sheets which contains data. I was hoping to use the code below to merge the content of the two files

$files = array("./admin/BHAA.Race.Master.xlsm", "/admin/clean-data-file.xlsx"); $merged = new ExcelMerge\ExcelMerge($files); $merged->download("my-filename.xlsm");

but what I am noticing is that the downloaded file contains 20 sheets. Could you advise how i might amend the existing code to merge the sheet content, such that i have ten sheets with data and macros. I'm happy to fork the repo and submit a push request but before I start I'd like to confirm this is in keeping with the vision you have for this tool.

Regards,
Paul

Excel with images

When merging excel with images, it doesn't add the images.
Tested on php7.0 and ubuntu 1604
best regards

Got error Undefined offset: 164

Please advice.

[ErrorException]
Undefined offset: 164

Here is trace:

 () at C:\vendor\infostreams\excel-merge\Tasks\Styles.php:175
 Illuminate\Foundation\Bootstrap\HandleExceptions->handleError() at C:\vendor\infostreams\ex
cel-merge\Tasks\Styles.php:175
 ExcelMerge\Tasks\Styles->rewriteCells() at C:\vendor\infostreams\excel-merge\Tasks\Styles.p
hp:51
 ExcelMerge\Tasks\Styles->merge() at C:\vendor\infostreams\excel-merge\ExcelMerge.php:134
 ExcelMerge\ExcelMerge->mergeWorksheets() at C:\vendor\infostreams\excel-merge\ExcelMerge.ph
p:55
 ExcelMerge\ExcelMerge->addFile() at C:\vendor\infostreams\excel-merge\ExcelMerge.php:40

I am using PHP 7.0.4 with Laravel 5.2

Directory name lost

Hi,

The directory name of $where is lost when using 'save' function.

You should keep PATHINFO_DIRNAME when defined.

Regards

Errors

  1. SharedStrings.php
    public function merge($zip_dir = null) {
    .....
    $target->documentElement->setAttribute('uniqueCount',count($shared_strings)); // <-- update uniqueCount
    $target->save($target_filename);

     return $mapping;
    

    }

  2. Styles.php
    styles from the first sheet are lost
    ***** Styles_new.php
    $new_id = count($defined_styles);
    $defined_styles[$new_id] = array( // <-- add new element
    "node" => $style,
    ***** STYLES_OLD.PHP
    $new_id = count($defined_styles);
    $defined_styles[$id] = array( // <-- owerwrite exist element
    "node" => $style,


Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.