我一直在我的应用程序的某些部分使用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;