phpexcel生成的xls文件以普通xml打开

时间:2017-08-18 11:45:24

标签: php xml zend-framework xls

我一直在我的应用程序的某些部分使用PHPexcel,它工作正常。在大多数情况下,由phpexcel创建的文件可以由libreoffice打开。但是在一个控制器中它会生成一个精细的xls文件。该文件可以下载。但每次我从libreoffice打开文件时它都会显示文本导入。然后该文件显示libreoffice calc中的实际xml文件。可能是什么问题呢?

private $workSheets = array();

private $styles = array();
private $view = null;
private $fileName = '';
private $translateHeaders = false;
private $translateValueColumns = array();
private $hideHeaderData = false;
private $dataSetHeaderStyleId = null;
private $cellStyleMap = array();

  public function __construct($fileName = '', Zend_View_Interface $view = null,
    $translateHeaders = false, $translateValueColumns = array(), $hideHeaderData = false)
{
    // Initialise worksheet collection and add one worksheet
    $this->workSheets = array();
    $this->workSheets[] = new  ExcelXML_WorkSheet($this);
    $this->view = $view;
    $this->fileName = $fileName;
    $this->translateHeaders = $translateHeaders;
    $this->translateValueColumns = $translateValueColumns;
    $this->hideHeaderData = $hideHeaderData;
    $this->initWorkBookStyle();
}
 public function __get($name)
{
    return $this->$name;
}

  public function __set($name, $value)
{
    $this->$name = $value;
}
  public function __isset($name) {
    return isset($this->$name);
}
  private function initWorkBookStyle()
{
    // Default text with single solid black lines as inner and outer borders.
    $this->addStyleFromArray(array(
        'borders' => array(
            'allborders' => array(
                'style' =>  ExcelXML_Style_Border::STYLE_CONTINUOUS,
                'weight' => 1,
                'color' => '#000000',
            ),
        ),
    ));

    // White bold text on a red background with single solid black lines as inner and outer borders.
    $this->dataSetHeaderStyleId = $this->addStyleFromArray(array(
        'font' => array(
            'bold' => true,
            'color' => '#FFFFFF'
        ),
        'alignment' => array(
            'horizontal' =>  ExcelXML_Style_Alignment::HORIZONTAL_CENTER,
            'vertical' =>  ExcelXML_Style_Alignment::VERTICAL_CENTER
        ),
        'fill' => array(
            'type' =>  ExcelXML_Style_Interior::PATTERN_SOLID,
            'color' => '#FF0000'
        ),
        'borders' => array(
            'allborders' => array(
                'style' =>  ExcelXML_Style_Border::STYLE_CONTINUOUS,
                'weight' => 1,
                'color' => '#000000'
            ),
        ),
    ));

    $this->cellStyleMap['h_center'] = $this->addStyleFromArray(array(
        'alignment' => array(
            'vertical' =>  ExcelXML_Style_Alignment::VERTICAL_CENTER,
            'horizontal' =>  ExcelXML_Style_Alignment::HORIZONTAL_CENTER
        )
    ));

    $this->cellStyleMap['h_left'] = $this->addStyleFromArray(array(
        'alignment' => array(
            'vertical' =>  ExcelXML_Style_Alignment::VERTICAL_CENTER,
            'horizontal' =>  ExcelXML_Style_Alignment::HORIZONTAL_LEFT
        )
    ));

    $this->cellStyleMap['h_right'] = $this->addStyleFromArray(array(
        'alignment' => array(
            'vertical' =>  ExcelXML_Style_Alignment::VERTICAL_CENTER,
            'horizontal' =>  ExcelXML_Style_Alignment::HORIZONTAL_RIGHT
        )
    ));

}
/**
 * Generate header xml of Workbook
 */
private function getHeader()
{
    echo '<?xml version="1.0" encoding="UTF-8"?><?mso-application progid="Excel.Sheet"?>
         <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
             xmlns:x="urn:schemas-microsoft-com:office:excel"
             xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
             xmlns:html="http://www.w3.org/TR/REC-html40">';
}

/**
 * Add Sheet to workbook
 * @param  ExcelXML_Worksheet $sheet
 */
public function addSheet($sheet)
{
    $this->workSheets[] = $sheet;
}

/**
 * Get Worksheet by name/title
 * @param string $name
 * @return  ExcelXML_Worksheet
 */
public function getSheetByName($name)
{
    $workSheet = null;
    $worksheetCount = count($this->workSheets);
    for ($i = 0; $i < $worksheetCount; $i++) {
        if ($this->workSheets[$i]->title == $name) {
            $workSheet = $this->workSheets[$i];
        }
    }

    return $workSheet;
}

/**
 * Get sheet by index
 *
 * @param int $sheetIndex Sheet index
 * @return  ExcelXML_Worksheet
 * @throws Exception
 */
public function getSheet($sheetIndex = 0)
{
    if (!isset($this->workSheets[$sheetIndex])) {
        throw new Exception("Sheet index is out of bounds.");
    }
    return $this->workSheets[$sheetIndex];
}

/**
 * Add style from array to Workbook
 * @param array $styleArray
 * @param boolean $isDefault
 * @param int $parentStyleId
 * @return int $styleId
 */
public function addStyleFromArray($styleArray = array(), $parentStyleId = null)
{
    $style = new  ExcelXML_Style();
    foreach ($styleArray as $styleName => $property) {
        switch ($styleName) {
            case  ExcelXML_Style::FONT:
                $bold = ($property['bold'] == true)? 1 : 0;
                $color = (!empty($property['color']))? $property['color'] : '';
                $fontName = (!empty($property['name']))? $property['name'] : '';
                $italic = (!empty($property['italic']))? 1 : 0;
                $style->setFont($bold, $color, $fontName, $italic);
                break;
            case  ExcelXML_Style::ALIGNMENT:
                $wraptext = !empty($property['wraptext'])? 1 : 0;
                $horizontal = !empty($property['horizontal'])? $property['horizontal'] : '';
                $vertical = !empty($property['vertical'])? $property['vertical'] : '';
                $style->setAlignment($wraptext, $horizontal, $vertical);
                break;
            case  ExcelXML_Style::INTERIOR:
                $color = (!empty($property['color']))? $property['color'] : '';
                $pattern = !empty($property['type'])? $property['type'] : 'solid';
                $style->setBackgroundColor($color, $pattern);
                break;
            case  ExcelXML_Style::BORDERS:
                if (!empty($property['allborders'])) {
                    $color = (!empty($property['allborders']['color']))? $property['allborders']['color'] : '';
                    $lineStyle = !empty($property['style'])? $property['style'] :  ExcelXML_Style_Border::STYLE_CONTINUOUS;
                    $weight = !empty($property['weight'])? $property['weight'] : 1;
                    $style->setBorder($color, $lineStyle, $weight);
                }
                break;
        }
    }
    return $this->setStyle($style, $parentStyleId);
}

/**
 * Set style object to Workbook
 *
 * @param  ExcelXML_Style $style
 * @param string $parentStyleId
 * @return int
 */
private function setStyle( ExcelXML_Style $style, $parentStyleId = null)
{
    $this->styles[] = $style;
    $styleId = count($this->styles);
    $style->setId($styleId);
    $style->setParentStyleId($parentStyleId);
    return $styleId;
}

/**
 * Set Header Data containing extra information to respective worksheet
 * @param array $headerDataArray
 */
public function setHeaderData($headerDataArray)
{
    foreach ($headerDataArray as $sheetIndex => $headerData) {
        $sheet = $this->getSheet($sheetIndex);
        $sheet->headerData = $headerData;
    }
}

/**
 * Set Column format Style to respective worksheet
 * @param array $columnFormatArray
 */
public function setColumnFormatData($columnFormatArray)
{
    foreach ($columnFormatArray as $sheetIndex => $columnFormat) {
        $sheet = $this->getSheet($sheetIndex);
        $sheet->columnFormat = $columnFormat;
    }
}

/**
 * Set Cell Styling to respective worksheet
 * @param array $cellFormatArray
 */
public function setCellFormatData($cellFormatArray)
{
    $hashKey = '';
    foreach ($cellFormatArray as $sheetIndex => $cellFormatData) {
        foreach ($cellFormatData as $row => $cellFormatByColumn) {
            foreach ($cellFormatByColumn as $column => $cellFormat) {
                $formatArray = !is_array($cellFormat['font'])? array($cellFormat['font']) : $cellFormat['font'];
                $fontStyleArray = array(
                    'bold' => in_array( Report_Report::FONT_FORMAT_BOLD, $formatArray),
                    'italic' => in_array( Report_Report::FONT_FORMAT_ITALIC, $formatArray),
                    'underline' => in_array( Report_Report::FONT_FORMAT_UNDERLINE, $formatArray)?  ExcelXML_Style_Font::UNDERLINE_SINGLE :  ExcelXML_Style_Font::UNDERLINE_NONE
                );
                $hashKey = $fontStyleArray['bold'].'|'.$fontStyleArray['italic'].'|'.$fontStyleArray['underline'];

                if (!isset($this->cellStyleMap[$hashKey])) {
                    $sheet = $this->getSheet($sheetIndex);
                    $columnAlignStyle = null;
                    $parentId = null;
                    if (isset($sheet->columnFormat[$column]) && isset($sheet->columnFormat[$column]['align'])) {
                        $columnAlignStyle = $sheet->columnFormat[$column]['align'];
                        if (isset($this->cellStyleMap['h_'.$columnAlignStyle])) {
                            $parentId = $this->cellStyleMap['h_'.$columnAlignStyle];
                        }
                    }
                    $this->cellStyleMap[$hashKey] = $this->addStyleFromArray(
                        array('font' => $fontStyleArray),
                        $parentId
                    );
                }
                if (isset($this->cellStyleMap[$hashKey])) {
                    $cellFormatArray[$sheetIndex][$row][$column] = $this->cellStyleMap[$hashKey];
                }
            }
        }
    }
    foreach ($cellFormatArray as $sheetIndex => $cellFormat) {
        $sheet = $this->getSheet($sheetIndex);
        $sheet->cellFormat = $cellFormat;
    }
}

/**
 * Set Column title to respective worksheet
 * @param array $columnTitleArray
 */
public function setColumnTitleData($columnTitleArray)
{
    foreach ($columnTitleArray as $sheetIndex => $columnTitles) {
        $sheet = $this->getSheet($sheetIndex);
        $sheet->columnTitles = $columnTitles;
    }
}

/**
 * Set Column Type to respective Worksheet
 * @param array $columnTypeArray
 */
public function setColumnTypeData($columnTypeArray)
{
    foreach ($columnTypeArray as $sheetIndex => $columnTypes) {
        $sheet = $this->getSheet($sheetIndex);
        $sheet->columnTypes = $columnTypes;
    }
}

/**
 * Set custom Dataset header to respective worksheet
 * @param array $dataSetHeaderArray
 */
public function setDataSetHeader($dataSetHeaderArray)
{
    foreach ($dataSetHeaderArray as $sheetIndex => $dataSetHeader) {
        $sheet = $this->getSheet($sheetIndex);
        $sheet->dataSetHeader = $dataSetHeader;
    }
}

/**
 * Set Excel Dataset to respective Worksheet
 * there could be multiple dataset for one worksheet
 *
 * @param array $dataSetArray
 */
public function setDataSet($dataSetArray)
{
    foreach ($dataSetArray as $sheetIndex => $dataSet) {
        $sheet = $this->getSheet($sheetIndex);
        if ($dataSet instanceof  Report_MultiDataSet) {
            foreach ($dataSet->dataSetArray as $dataSet) {
                $sheet->setDataSetList($dataSet);
            }
        } else {
            $sheet->setDataSetList($dataSet);
        }
    }
}

/**
 * Render WorkBook Style as XML
 */
private function renderStyleAsXml()
{
    if (count($this->styles) > 0) {
        $styleXml = '<ss:Styles>';
        foreach ($this->styles as $style) {
            $styleXml .= $style->asXml();
        }
        $styleXml .= '</ss:Styles>';
    }
    echo $styleXml;
}

/**
 * Get Footer of the workbook to end file
 */
private function getFooter()
{
    echo '</Workbook>';
}

/**
 * Set All necessary header to make file downloadable as excel xml
 */
private function outputExcelHeaders()
{
    ini_set('zlib.output_compression','Off');

    // set the headers
    header('Pragma: public');
    header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");                 // Date in the past
    header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
    header('Cache-Control: no-store, no-cache, must-revalidate');     // HTTP/1.1
    header('Cache-Control: pre-check=0, post-check=0, max-age=0');    // HTTP/1.1
    header("Pragma: no-cache");
    header("Expires: 0");
    header('Content-Description: File Transfer');
    header('Content-Transfer-Encoding: none');
    header('Content-Type: application/vnd.ms-excel;');                 // This should work for IE & Opera
    header("Content-type: application/x-msexcel");                     // This should work for the rest
    header('Content-Disposition: attachment; filename="'.basename($this->fileName).'.xml"');
}

/**
 * Prepare Excel with provided data before
 */
private function prepareExcel()
{
    $this->getHeader();
    $this->renderStyleAsXml();
    foreach ($this->workSheets as $sheetIndex => $sheet) {
        $sheet->render();
    }
    $this->getFooter();
}

/**
 * Render ExcelXML file and give to download
 */
public function render()
{
    $this->outputExcelHeaders();
    $this->prepareExcel();
}

/**
 * Prepare and Save File to given path
 * @param string $path
 */
public function save($path)
{
    ob_start();
    $this->prepareExcel();
    file_put_contents($path.DIRECTORY_SEPARATOR.$this->fileName, ob_get_contents());
    ob_end_clean();
}

/**
 * Get Content of file to send as attachment in email
 * @return Zend_Mime_Part
 */
public function renderAsMimePart()
{
    ob_start();
    $this->prepareExcel();

    $mimePart = new Zend_Mime_Part(ob_get_contents());
    $mimePart->encoding = Zend_Mime::ENCODING_BASE64;
    $mimePart->type = 'application/x-msexcel';
    $mimePart->disposition = 'attachment';
    $mimePart->filename = $this->fileName.'.xml';

    ob_end_clean();
    return $mimePart;
}

类ExcelXML_WorkBook {

import React, { Component } from 'react'
import { render } from 'react-dom'
//import { Provider } from 'react-redux'
//import { createStore } from 'redux'

import MapChart from './modules/mapChart/MapChart'
import './index.css'

// this is how you'll get your icon links
// instead of a switch with loads of repetitive bytes
const iconMap = {
  'anti-social-behaviour':  'green-dot',
  'burglary':               'red-dot',
  'criminal-damage-arson':  'yellow-dot',
  'drugs':                  'purple-dot',
  'other-theft':            'pink-dot',
  'shoplifting':            'blue-dot',
  'vehicle-crime':          'orange-dot',
  'other-crime':            'ltblue-dot'
}

// this is a class because it needs state
class CrimeMap extends Component {
  // to do this you have to make sure you have
  // the transform-class-properties feature in babel
  // otherwise just set your initial state in a constructor
  // constructor(props) {
  //   super(props)
  //   this.state = { markers: [] }
  // }
  state = {
    markers: []
  }

  componentDidMount() {
    // use fetch instead of jQuery
    // jQuery is a big lib to be loading for some fetching
    fetch(this.props.source)
      .then( response => response.json() )
      .then(
        json => this.setState({
          markers: this.mapLayerData(json)
        }),
        err => { 
          // handle errors 
        }
      )
  }

  // store only the data you want to pass as props to each Marker
  // instead of mapping it directly in MapChart every time it renders
  mapLayerData(markers) {
    // use a standard map function instead of $.each
    // destructuring saves time and repetition
    return markers.map(({ category, location }) => ({
      // use a template string and a simple map of icon names to get your icon uri
      icon: 'http://maps.google.com/mapfiles/ms/icons/'+ iconMap[category] +'.png',
      label: category,
      name: category,
      position: {
        lat: location.latitude,
        lng: location.longitude
      }
    }))
  }

  render() {
    // there's only one layer, so render it directly
    return (
      <div className="app">
        <MapChart markers={this.state.markers} />
      </div>
    )
  }
}

//https://data.police.uk/docs/method/crime-street/
render(
    <CrimeMap source="https://data.police.uk/api/crimes-street/all-crime?poly=52.268,0.543:52.794,0.238:52.130,0.478&date=2017-01" />,
    document.getElementById('root')
);

}

&GT;

0 个答案:

没有答案