diff --git a/.gitignore b/.gitignore
index dea03b5e1..f76f37bd2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,4 @@ analysis
 *.project
 /.settings
 /.idea
+/unitTests/phpunit
diff --git a/Classes/PHPExcel/Reader/OOCalc.php b/Classes/PHPExcel/Reader/OOCalc.php
index a889d9570..5251df6f4 100644
--- a/Classes/PHPExcel/Reader/OOCalc.php
+++ b/Classes/PHPExcel/Reader/OOCalc.php
@@ -34,34 +34,31 @@
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  * @version    ##VERSION##, ##DATE##
  */
-class PHPExcel_Reader_OOCalc extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader
-{
+class PHPExcel_Reader_OOCalc extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader {
     /**
      * Formats
      *
      * @var array
      */
-    private $styles = array();
+    private $styles = [];
 
     /**
      * Create a new PHPExcel_Reader_OOCalc
      */
-    public function __construct()
-    {
-        $this->readFilter     = new PHPExcel_Reader_DefaultReadFilter();
+    public function __construct(){
+        $this->readFilter = new PHPExcel_Reader_DefaultReadFilter();
     }
 
     /**
      * Can the current PHPExcel_Reader_IReader read the file?
      *
-     * @param     string         $pFilename
+     * @param     string $pFilename
      * @return     boolean
      * @throws PHPExcel_Reader_Exception
      */
-    public function canRead($pFilename)
-    {
+    public function canRead($pFilename){
         // Check if file exists
-        if (!file_exists($pFilename)) {
+        if(!file_exists($pFilename)){
             throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
         }
 
@@ -75,20 +72,21 @@ public function canRead($pFilename)
         $mimeType = 'UNKNOWN';
         // Load file
         $zip = new $zipClass;
-        if ($zip->open($pFilename) === true) {
+        if($zip->open($pFilename) === true){
             // check if it is an OOXML archive
             $stat = $zip->statName('mimetype');
-            if ($stat && ($stat['size'] <= 255)) {
+            if($stat && ($stat['size'] <= 255)){
                 $mimeType = $zip->getFromName($stat['name']);
-            } elseif ($stat = $zip->statName('META-INF/manifest.xml')) {
+            }
+            elseif($stat = $zip->statName('META-INF/manifest.xml')){
                 $xml = simplexml_load_string($this->securityScan($zip->getFromName('META-INF/manifest.xml')), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());
                 $namespacesContent = $xml->getNamespaces(true);
-                if (isset($namespacesContent['manifest'])) {
+                if(isset($namespacesContent['manifest'])){
                     $manifest = $xml->children($namespacesContent['manifest']);
-                    foreach ($manifest as $manifestDataSet) {
+                    foreach($manifest as $manifestDataSet){
                         $manifestAttributes = $manifestDataSet->attributes($namespacesContent['manifest']);
-                        if ($manifestAttributes->{'full-path'} == '/') {
-                            $mimeType = (string) $manifestAttributes->{'media-type'};
+                        if($manifestAttributes->{'full-path'} == '/'){
+                            $mimeType = (string)$manifestAttributes->{'media-type'};
                             break;
                         }
                     }
@@ -107,48 +105,48 @@ public function canRead($pFilename)
     /**
      * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object
      *
-     * @param     string         $pFilename
+     * @param     string $pFilename
      * @throws     PHPExcel_Reader_Exception
      */
-    public function listWorksheetNames($pFilename)
-    {
+    public function listWorksheetNames($pFilename){
         // Check if file exists
-        if (!file_exists($pFilename)) {
+        if(!file_exists($pFilename)){
             throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
         }
 
         $zipClass = PHPExcel_Settings::getZipClass();
 
         $zip = new $zipClass;
-        if (!$zip->open($pFilename)) {
+        if(!$zip->open($pFilename)){
             throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! Error opening file.");
         }
 
-        $worksheetNames = array();
+        $worksheetNames = [];
 
         $xml = new XMLReader();
-        $res = $xml->xml($this->securityScanFile('zip://'.realpath($pFilename).'#content.xml'), null, PHPExcel_Settings::getLibXmlLoaderOptions());
+        $res = $xml->xml($this->securityScanFile('zip://' . realpath($pFilename) . '#content.xml'), null, PHPExcel_Settings::getLibXmlLoaderOptions());
         $xml->setParserProperty(2, true);
 
         //    Step into the first level of content of the XML
         $xml->read();
-        while ($xml->read()) {
+        while($xml->read()){
             //    Quickly jump through to the office:body node
-            while ($xml->name !== 'office:body') {
-                if ($xml->isEmptyElement) {
+            while($xml->name !== 'office:body'){
+                if($xml->isEmptyElement){
                     $xml->read();
-                } else {
+                }
+                else{
                     $xml->next();
                 }
             }
             //    Now read each node until we find our first table:table node
-            while ($xml->read()) {
-                if ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT) {
+            while($xml->read()){
+                if($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT){
                     //    Loop through each table:table node reading the table:name attribute for each worksheet name
-                    do {
+                    do{
                         $worksheetNames[] = $xml->getAttribute('table:name');
                         $xml->next();
-                    } while ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT);
+                    }while($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT);
                 }
             }
         }
@@ -159,58 +157,58 @@ public function listWorksheetNames($pFilename)
     /**
      * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns)
      *
-     * @param   string     $pFilename
+     * @param   string $pFilename
      * @throws   PHPExcel_Reader_Exception
      */
-    public function listWorksheetInfo($pFilename)
-    {
+    public function listWorksheetInfo($pFilename){
         // Check if file exists
-        if (!file_exists($pFilename)) {
+        if(!file_exists($pFilename)){
             throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
         }
 
-        $worksheetInfo = array();
+        $worksheetInfo = [];
 
         $zipClass = PHPExcel_Settings::getZipClass();
 
         $zip = new $zipClass;
-        if (!$zip->open($pFilename)) {
+        if(!$zip->open($pFilename)){
             throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! Error opening file.");
         }
 
         $xml = new XMLReader();
-        $res = $xml->xml($this->securityScanFile('zip://'.realpath($pFilename).'#content.xml'), null, PHPExcel_Settings::getLibXmlLoaderOptions());
+        $res = $xml->xml($this->securityScanFile('zip://' . realpath($pFilename) . '#content.xml'), null, PHPExcel_Settings::getLibXmlLoaderOptions());
         $xml->setParserProperty(2, true);
 
         //    Step into the first level of content of the XML
         $xml->read();
-        while ($xml->read()) {
+        while($xml->read()){
             //    Quickly jump through to the office:body node
-            while ($xml->name !== 'office:body') {
-                if ($xml->isEmptyElement) {
+            while($xml->name !== 'office:body'){
+                if($xml->isEmptyElement){
                     $xml->read();
-                } else {
+                }
+                else{
                     $xml->next();
                 }
             }
-                //    Now read each node until we find our first table:table node
-            while ($xml->read()) {
-                if ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT) {
+            //    Now read each node until we find our first table:table node
+            while($xml->read()){
+                if($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT){
                     $worksheetNames[] = $xml->getAttribute('table:name');
 
-                    $tmpInfo = array(
+                    $tmpInfo = [
                         'worksheetName' => $xml->getAttribute('table:name'),
                         'lastColumnLetter' => 'A',
                         'lastColumnIndex' => 0,
                         'totalRows' => 0,
                         'totalColumns' => 0,
-                    );
+                    ];
 
                     //    Loop through each child node of the table:table element reading
                     $currCells = 0;
-                    do {
+                    do{
                         $xml->read();
-                        if ($xml->name == 'table:table-row' && $xml->nodeType == XMLReader::ELEMENT) {
+                        if($xml->name == 'table:table-row' && $xml->nodeType == XMLReader::ELEMENT){
                             $rowspan = $xml->getAttribute('table:number-rows-repeated');
                             $rowspan = empty($rowspan) ? 1 : $rowspan;
                             $tmpInfo['totalRows'] += $rowspan;
@@ -218,22 +216,24 @@ public function listWorksheetInfo($pFilename)
                             $currCells = 0;
                             //    Step into the row
                             $xml->read();
-                            do {
-                                if ($xml->name == 'table:table-cell' && $xml->nodeType == XMLReader::ELEMENT) {
-                                    if (!$xml->isEmptyElement) {
+                            do{
+                                if($xml->name == 'table:table-cell' && $xml->nodeType == XMLReader::ELEMENT){
+                                    if(!$xml->isEmptyElement){
                                         $currCells++;
                                         $xml->next();
-                                    } else {
+                                    }
+                                    else{
                                         $xml->read();
                                     }
-                                } elseif ($xml->name == 'table:covered-table-cell' && $xml->nodeType == XMLReader::ELEMENT) {
+                                }
+                                elseif($xml->name == 'table:covered-table-cell' && $xml->nodeType == XMLReader::ELEMENT){
                                     $mergeSize = $xml->getAttribute('table:number-columns-repeated');
                                     $currCells += $mergeSize;
                                     $xml->read();
                                 }
-                            } while ($xml->name != 'table:table-row');
+                            }while($xml->name != 'table:table-row');
                         }
-                    } while ($xml->name != 'table:table');
+                    }while($xml->name != 'table:table');
 
                     $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'], $currCells);
                     $tmpInfo['lastColumnIndex'] = $tmpInfo['totalColumns'] - 1;
@@ -284,12 +284,11 @@ public function listWorksheetInfo($pFilename)
     /**
      * Loads PHPExcel from file
      *
-     * @param     string         $pFilename
+     * @param     string $pFilename
      * @return     PHPExcel
      * @throws     PHPExcel_Reader_Exception
      */
-    public function load($pFilename)
-    {
+    public function load($pFilename){
         // Create new PHPExcel
         $objPHPExcel = new PHPExcel();
 
@@ -297,29 +296,31 @@ public function load($pFilename)
         return $this->loadIntoExisting($pFilename, $objPHPExcel);
     }
 
-    private static function identifyFixedStyleValue($styleList, &$styleAttributeValue)
-    {
+    private static function identifyFixedStyleValue($styleList, &$styleAttributeValue){
         $styleAttributeValue = strtolower($styleAttributeValue);
-        foreach ($styleList as $style) {
-            if ($styleAttributeValue == strtolower($style)) {
+        foreach($styleList as $style){
+            if($styleAttributeValue == strtolower($style)){
                 $styleAttributeValue = $style;
+
                 return true;
             }
         }
+
         return false;
     }
 
     /**
      * Loads PHPExcel from file into PHPExcel instance
      *
-     * @param     string         $pFilename
-     * @param    PHPExcel    $objPHPExcel
+     * @param     string $pFilename
+     * @param    PHPExcel $objPHPExcel
      * @return     PHPExcel
      * @throws     PHPExcel_Reader_Exception
      */
     public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel)
     {
-        // Check if file exists
+
+// Check if file exists
         if (!file_exists($pFilename)) {
             throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
         }
@@ -329,6 +330,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel)
 
         $zipClass = PHPExcel_Settings::getZipClass();
 
+        /** @var \ZipArchive $zip */
         $zip = new $zipClass;
         if (!$zip->open($pFilename)) {
             throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! Error opening file.");
@@ -429,9 +431,13 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel)
 
         $workbook = $xml->children($namespacesContent['office']);
         foreach ($workbook->body->spreadsheet as $workbookData) {
+            /** @var \SimpleXMLElement $workbookData */
+
             $workbookData = $workbookData->children($namespacesContent['table']);
             $worksheetID = 0;
             foreach ($workbookData->table as $worksheetDataSet) {
+                /** @var \SimpleXMLElement $worksheetDataSet */
+
                 $worksheetData = $worksheetDataSet->children($namespacesContent['table']);
 //                print_r($worksheetData);
 //                echo '
';
@@ -457,6 +463,8 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel)
 
                 $rowID = 1;
                 foreach ($worksheetData as $key => $rowData) {
+                    /** @var \SimpleXMLElement $rowData */
+
 //                    echo ''.$key.'
';
                     switch ($key) {
                         case 'table-header-rows':
@@ -469,6 +477,8 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel)
                             $rowRepeats = (isset($rowDataTableAttributes['number-rows-repeated'])) ? $rowDataTableAttributes['number-rows-repeated'] : 1;
                             $columnID = 'A';
                             foreach ($rowData as $key => $cellData) {
+                                /** @var \SimpleXMLElement $cellData */
+
                                 if ($this->getReadFilter() !== null) {
                                     if (!$this->getReadFilter()->readCell($columnID, $rowID, $worksheetName)) {
                                         continue;
@@ -524,16 +534,33 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel)
                                     // Also, here we assume there is no text data is span fields are specified, since
                                     // we have no way of knowing proper positioning anyway.
                                     foreach ($cellDataText->p as $pData) {
-                                        if (isset($pData->span)) {
-                                            // span sections do not newline, so we just create one large string here
-                                            $spanSection = "";
-                                            foreach ($pData->span as $spanData) {
-                                                $spanSection .= $spanData;
-                                            }
-                                            array_push($dataArray, $spanSection);
-                                        } else {
-                                            array_push($dataArray, $pData);
-                                        }
+                                        /** @var \SimpleXMLElement $pData */
+
+//                                        if (isset($pData->span)) {
+//                                            // span sections do not newline, so we just create one large string here
+//                                            $spanSection = "";
+//                                            foreach ($pData->span as $spanData) {
+//                                                /** @var \SimpleXMLElement $spanData */
+//
+//                                                $spanSection .= $spanData;
+//                                            }
+//                                            array_push($dataArray, $spanSection);
+//                                        } else {
+
+                                            // SimpleXML sucks, need to use DOMDocument instead
+                                            libxml_use_internal_errors(true);
+
+                                            $doc = new \DOMDocument("1.0");
+                                            $doc->loadXML($pData->saveXML());
+
+                                            $str = $this->scanElement($doc->childNodes->item(0));
+
+                                            unset($doc);
+
+                                            libxml_use_internal_errors(false);
+
+                                            array_push($dataArray, $str);
+//                                        }
                                     }
                                     $allCellDataText = implode($dataArray, "\n");
 
@@ -685,6 +712,46 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel)
         return $objPHPExcel;
     }
 
+    /**
+     * Recursively scan element
+     *
+     * @param DOMNode $element
+     * @return string
+     */
+    protected function scanElement(DOMNode $element){
+
+        $str = "";
+        foreach($element->childNodes as $child){
+            /** @var \DOMNode $child */
+
+            if($child->nodeType == XML_TEXT_NODE){
+                $str .= $child->nodeValue;
+            }
+            elseif($child->nodeType == XML_ELEMENT_NODE && $child->nodeName == "text:s"){
+                // It's a space
+
+                // Multiple spaces?
+                if(isset($child->attributes["text:c"])){
+
+                    /** @var \DOMAttr $cAttr */
+                    $cAttr = $child->attributes["text:c"];
+                    $multiplier = (int)$cAttr->nodeValue;
+                }
+                else{
+                    $multiplier = 1;
+                }
+
+                $str .= str_repeat(" ", $multiplier);
+            }
+
+            if($child->hasChildNodes()){
+                $str .= $this->scanElement($child);
+            }
+        }
+
+        return $str;
+    }
+
     private function parseRichText($is = '')
     {
         $value = new PHPExcel_RichText();
diff --git a/Classes/PHPExcel/Writer/OpenDocument/Content.php b/Classes/PHPExcel/Writer/OpenDocument/Content.php
index a34b1670c..3f8384df6 100644
--- a/Classes/PHPExcel/Writer/OpenDocument/Content.php
+++ b/Classes/PHPExcel/Writer/OpenDocument/Content.php
@@ -33,11 +33,13 @@
  * @package    PHPExcel_Writer_OpenDocument
  * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @author     Alexander Pervakov 
+ * @author     Paolo Agostinetto 
  */
 class PHPExcel_Writer_OpenDocument_Content extends PHPExcel_Writer_OpenDocument_WriterPart
 {
     const NUMBER_COLS_REPEATED_MAX = 1024;
     const NUMBER_ROWS_REPEATED_MAX = 1048576;
+    const CELL_STYLE_PREFIX = 'ce';
 
     /**
      * Write content.xml to XML format
@@ -100,7 +102,11 @@ public function write(PHPExcel $pPHPExcel = null)
 
             $objWriter->writeElement('office:scripts');
             $objWriter->writeElement('office:font-face-decls');
-            $objWriter->writeElement('office:automatic-styles');
+
+            // Styles XF
+            $objWriter->startElement('office:automatic-styles');
+            $this->writeXfStyles($objWriter, $pPHPExcel);
+            $objWriter->endElement();
 
             $objWriter->startElement('office:body');
                 $objWriter->startElement('office:spreadsheet');
@@ -186,12 +192,20 @@ private function writeCells(PHPExcel_Shared_XMLWriter $objWriter, PHPExcel_Works
         $prev_column = -1;
         $cells = $row->getCellIterator();
         while ($cells->valid()) {
+
+            /** @var PHPExcel_Cell $cell */
             $cell = $cells->current();
             $column = PHPExcel_Cell::columnIndexFromString($cell->getColumn()) - 1;
 
             $this->writeCellSpan($objWriter, $column, $prev_column);
             $objWriter->startElement('table:table-cell');
 
+            // Style XF
+            $style = $cell->getXfIndex();
+            if($style !== null){
+                $objWriter->writeAttribute('table:style-name', self::CELL_STYLE_PREFIX.$style);
+            }
+
             switch ($cell->getDataType()) {
                 case PHPExcel_Cell_DataType::TYPE_BOOL:
                     $objWriter->writeAttribute('office:value-type', 'boolean');
@@ -269,4 +283,92 @@ private function writeCellSpan(PHPExcel_Shared_XMLWriter $objWriter, $curColumn,
             $objWriter->endElement();
         }
     }
+
+    /**
+     * Write XF cell styles
+     *
+     * @param PHPExcel_Shared_XMLWriter $objWriter
+     * @param PHPExcel $pPHPExcel
+     * @throws PHPExcel_Exception
+     */
+    private function writeXfStyles(PHPExcel_Shared_XMLWriter $objWriter, PHPExcel $pPHPExcel)
+    {
+        foreach($pPHPExcel->getCellXfCollection() as $style) {
+
+            $objWriter->startElement('style:style');
+            $objWriter->writeAttribute('style:name', self::CELL_STYLE_PREFIX .$style->getIndex());
+            $objWriter->writeAttribute('style:family', 'table-cell');
+            $objWriter->writeAttribute('style:parent-style-name', 'Default');
+
+            /*
+             * style:text-properties
+             */
+
+            // Font
+            $objWriter->startElement('style:text-properties');
+
+            $font = $style->getFont();
+
+            if($font->getBold()) {
+                $objWriter->writeAttribute('fo:font-weight', 'bold');
+                $objWriter->writeAttribute('style:font-weight-complex', 'bold');
+                $objWriter->writeAttribute('style:font-weight-asian', 'bold');
+            }
+
+            if($font->getItalic()) {
+                $objWriter->writeAttribute('fo:font-style', 'italic');
+            }
+
+            if($color = $font->getColor()) {
+                $objWriter->writeAttribute('fo:color', sprintf('#%s', $color->getRGB()));
+            }
+
+            if($size = $font->getSize()) {
+                $objWriter->writeAttribute('fo:font-size', sprintf('%.1fpt', $size));
+            }
+
+            if($font->getUnderline() == \PHPExcel_Style_Font::UNDERLINE_SINGLE) {
+                $objWriter->writeAttribute('style:text-underline-style', 'solid');
+                $objWriter->writeAttribute('style:text-underline-width', 'auto');
+                $objWriter->writeAttribute('style:text-underline-color', 'font-color');
+            }
+
+            $objWriter->endElement(); // Close style:text-properties
+
+            /*
+             * style:table-cell-properties
+             */
+
+            $objWriter->startElement('style:table-cell-properties');
+            $objWriter->writeAttribute('style:rotation-align', 'none');
+
+            // Fill
+            if($fill = $style->getFill()) {
+                switch($fill->getFillType()) {
+
+                    case \PHPExcel_Style_Fill::FILL_SOLID:
+                        $objWriter->writeAttribute('fo:background-color', sprintf('#%s',
+                            strtolower($fill->getStartColor()->getRGB())
+                        ));
+                        break;
+
+                    case \PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR:
+                    case \PHPExcel_Style_Fill::FILL_GRADIENT_PATH:
+                        /// TODO :: To be implemented
+                        break;
+
+                    case \PHPExcel_Style_Fill::FILL_NONE:
+                    default:
+                }
+            }
+
+            $objWriter->endElement(); // Close style:table-cell-properties
+
+            /*
+             * End
+             */
+
+            $objWriter->endElement(); // Close style:style
+        }
+    }
 }
diff --git a/unitTests/Classes/PHPExcel/Reader/OOCalcTest.php b/unitTests/Classes/PHPExcel/Reader/OOCalcTest.php
new file mode 100644
index 000000000..16f0df089
--- /dev/null
+++ b/unitTests/Classes/PHPExcel/Reader/OOCalcTest.php
@@ -0,0 +1,26 @@
+load(__DIR__."/../../../rawTestData/Reader/OOCalc/spaces-everywhere.ods");
+
+        $arr = $file->getActiveSheet()->toArray();
+
+        $this->assertEquals([
+            ["This has    4 spaces before and 2 after  "],
+            ["This only one after "],
+            ["Test with DIFFERENT styles     and multiple spaces:  "],
+            ["test with new \nLines"],
+        ], $arr);
+    }
+}
diff --git a/unitTests/rawTestData/Reader/OOCalc/spaces-everywhere.ods b/unitTests/rawTestData/Reader/OOCalc/spaces-everywhere.ods
new file mode 100644
index 000000000..2c0867252
Binary files /dev/null and b/unitTests/rawTestData/Reader/OOCalc/spaces-everywhere.ods differ