我正在使用(尝试使用)PHPExcel将数组传递给excel,我已经定义了标题,我希望数组中的每个数组都在一个单独的行中。
但是,这只会将标题放在excel文件中,而不是数组中的数据。我做错了什么?我怎样才能让它发挥作用?
脚本:
<?php
$databasehost = "localhost";
$databasename = "dummydata";
$databasetable = "import1";
$databasetable2 = "data1";
$databaseusername ="dummydata";
$databasepassword = "dummydata";
$con = @mysql_connect($databasehost,$databaseusername,$databasepassword) or die(mysql_error());
@mysql_select_db($databasename) or die(mysql_error());
$query = mysql_query("SELECT * from $databasetable;");
$data = array();
$index = 0;
while($row = mysql_fetch_assoc($query))
{
$data[$index] = $row;
$index++;
}
foreach ($data as $key) {
$url = 'http://maps.googleapis.com/maps/api/geocode/json?latlng='.$key['latitude'].','.$key['longitude'].'&sensor=true';
$json = file_get_contents($url);
$dataReceived = json_decode($json, TRUE);
//echo '<pre>'; print_r($dataReceived['results']); echo '</pre>';
$compiled = array();
$index = 0;
foreach ($dataReceived['results'] as $value) {
$compiled[$index] = array(
'ref' => $key['id']);
foreach ($value['address_components'] as $value2)
{
$compiled[$index][$value2['types'][0]] = $value2['long_name'];
}
$index++;
}
$sortedData = array();
$index = 0;
foreach ($compiled as $value) {
//echo '<pre>'; print_r($value); echo '</pre>';
$sortedData[$index] = array(
'ref' => $value['ref'],
'lat' => $key['latitude'],
'long' => $key['longitude'],
'route' => $value['route'],
'locality' => $value['locality'],
'administrative_area_level_2' => $value['administrative_area_level_2'],
'administrative_area_level_1' => $value['administrative_area_level_1'],
'country' => $value['country'],
'postal_code_prefix' => $value['postal_code_prefix'],
'postal_town' => $value['postal_town'],
'postal_code' => $value['postal_code'],
'administrative_area_level_3' => $value['administrative_area_level_3'],
'street_number' => $value['street_number'],
'establishment' => $value['establishment'],
);
$index++;
}
echo '<pre>';print_r($sortedData);echo "</pre>";
/*$query = mysql_query("INSERT INTO $databasetable2
ref, lat, long, route, locality, administrative_area_level_2, administrative_area_level_1, country, postal_code_prefix, postal_town)
VALUES
()");*/
}
@mysql_close($con);
/**
* PHPExcel
*
* Copyright (C) 2006 - 2011 PHPExcel
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* @category PHPExcel
* @package PHPExcel
* @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel)
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
* @version ##VERSION##, ##DATE##
*/
/** Error reporting */
error_reporting(E_ALL);
ini_set('display_errors', '1');
date_default_timezone_set('Europe/London');
/** PHPExcel */
require_once 'Classes/PHPExcel.php';
// Create new PHPExcel object
//echo date('H:i:s') . " Create new PHPExcel object\n";
$objPHPExcel = new PHPExcel();
// Set properties
//echo date('H:i:s') . " Set properties\n";
$objPHPExcel->getProperties()->setCreator("Anon")
->setLastModifiedBy("Anon")
->setTitle("Crawler Data");
// Add some data
//echo date('H:i:s') . " Add some data\n";
$objPHPExcel->setActiveSheetIndex(0)
->setCellValue('A1', 'ref')
->setCellValue('B1', 'latitude')
->setCellValue('C1', 'longitude')
->setCellValue('D1', 'route')
->setCellValue('E1', 'locality')
->setCellValue('F1', 'administrative_area_level_2')
->setCellValue('G1', 'administrative_area_level_1')
->setCellValue('H1', 'country')
->setCellValue('I1', 'postal_code_prefix')
->setCellValue('J1', 'postal_town')
->setCellValue('K1', 'postal_code')
->setCellValue('L1', 'administrative_area_level_3')
->setCellValue('M1', 'street_number')
->setCellValue('N1', 'establishment');
//$objPHPExcel->getActiveSheet()->fromArray($sortedData, null, 'A2');
// Set active sheet index to the first sheet, so Excel opens this as the first sheet
$objPHPExcel->setActiveSheetIndex(0);
// Save Excel 2007 file
//echo date('H:i:s') . " Write to Excel2007 format\n";
//!!!!!!!!!!!!!!!!!!!-------- I Change 'Excel2007' to 'Excel5' ------!!!!!!!!!!!!!!!!!!!!!!!!
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
//!!!!!!!!!!!!!!!!!!!-------- I Change '.xlsx' to '.xls' ------!!!!!!!!!!!!!!!!!!!!!!!!
$objWriter->save(str_replace('.php', '.xls', __FILE__));
// Echo memory peak usage
//echo date('H:i:s') . " Peak memory usage: " . (memory_get_peak_usage(true) / 1024 / 1024) . " MB\r\n";
// Echo done
//echo date('H:i:s') . " Done writing file.\r\n";
?>
文件现在看起来像:
<?php
require_once 'Classes/PHPExcel.php';
date_default_timezone_set('Europe/London');
$databasehost = "localhost";
$databasename = "ryansmur_crawler";
$databasetable = "import1";
$databasetable2 = "data1";
$databaseusername ="ryansmur_admin";
$databasepassword = "Penelope1";
$con = @mysql_connect($databasehost,$databaseusername,$databasepassword) or die(mysql_error());
@mysql_select_db($databasename) or die(mysql_error());
$query = mysql_query("SELECT * from $databasetable;");
$data = array();
$index = 0;
while($row = mysql_fetch_assoc($query))
{
$data[$index] = $row;
$index++;
}
$headers = array(
'ref', 'lat', 'long', 'route', 'locality', 'administrative_area_level_2',
'administrative_area_level_1', 'country', 'postal_code_prefix',
'postal_town', 'postal_code', 'administrative_area_level_3',
'street_number', 'establishment',
);
$addRowCreate = function(PHPExcel_Worksheet $sheet, $col = 'A', $row = NULL) {
return function(array $data) use ($sheet, $col, &$row) {
if ($row === NULL) {
$row = $sheet->getHighestRow() + 1;
}
$sheet->fromArray(array($data), NULL, "$col$row");
$row++;
};
};
$doc = new PHPExcel();
$doc->getProperties()->setCreator("Anon")
->setLastModifiedBy("Anon")
->setTitle("Crawler Data");
$sheet = $doc->setActiveSheetIndex(0);
$sheet->fromArray($headers);
$addRow = $addRowCreate($sheet);
foreach ($data as $key) {
$url = 'http://maps.googleapis.com/maps/api/geocode/json?latlng='.$key['latitude'].','.$key['longitude'].'&sensor=true';
$json = file_get_contents($url);
$dataReceived = json_decode($json, TRUE);
$compiled = array();
$index = 0;
foreach ($dataReceived['results'] as $value) {
$compiled[$index] = array(
'ref' => $key['id']);
foreach ($value['address_components'] as $value2)
{
$compiled[$index][$value2['types'][0]] = $value2['long_name'];
}
$index++;
}
$sortedData = array();
$index = 0;
foreach ($compiled as $value) {
$addRow(array(
'ref' => $value['ref'],
'lat' => $key['latitude'],
'long' => $key['longitude'],
'route' => $value['route'],
'locality' => $value['locality'],
'administrative_area_level_2' => $value['administrative_area_level_2'],
'administrative_area_level_1' => $value['administrative_area_level_1'],
'country' => $value['country'],
'postal_code_prefix' => $value['postal_code_prefix'],
'postal_town' => $value['postal_town'],
'postal_code' => $value['postal_code'],
'administrative_area_level_3' => $value['administrative_area_level_3'],
'street_number' => $value['street_number'],
'establishment' => $value['establishment'],
));
$index++;
}
}
@mysql_close($con);
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
$objWriter->save(str_replace('.php', '.xls', __FILE__));
echo date('H:i:s') . " Done writing file.\r\n";
?>
答案 0 :(得分:3)
重新阅读你的代码,它看起来很混乱。我认为可以在许多方面进行改进,但是对于最少更改,我建议您执行以下操作:
不是首先创建要添加的多个行数组,而是每次创建时添加一个新行。为此,您甚至不需要为键命名。所以在之前迭代数据库结果,首先创建标题(我将其命名为$headers
):
$headers = array(
'ref', 'lat', 'long', 'route', 'locality', 'administrative_area_level_2',
'administrative_area_level_1', 'country', 'postal_code_prefix',
'postal_town', 'postal_code', 'administrative_area_level_3',
'street_number', 'establishment',
);
同样在数据库迭代之前,创建一个辅助函数:
$addRowCreate = function(PHPExcel_Worksheet $sheet, $col = 'A', $row = NULL) {
return function(array $data) use ($sheet, $col, &$row) {
if ($row === NULL) {
$row = $sheet->getHighestRow() + 1;
}
$sheet->fromArray(array($data), NULL, "$col$row");
$row++;
};
};
这个$addRowCreate
辅助函数将允许您稍后创建一个add-row-function,就像在一秒钟内一样。在数据库迭代之前,创建excel文档(内存)并设置它的属性。还要在第一行添加标题:
$doc = new PHPExcel();
$doc->getProperties()->setCreator("Anon")
->setLastModifiedBy("Anon")
->setTitle("Crawler Data");
$sheet = $doc->setActiveSheetIndex(0);
$sheet->fromArray($headers);
下一步是创建add-row-function,由于上面的帮助器,非常很容易:
$addRow = $addRowCreate($sheet);
现在,您可以通过每行数组调用一次来使用一行。出于测试目的,只需添加另一行并将其保存到磁盘:
$addRow($headers);
$writer = PHPExcel_IOFactory::createWriter($doc, 'Excel5');
$writer->save(basename(__FILE__, '.php') . '.xls');
die('test finished.');
您现在应该创建包含两行的xls文件。然后,您可以再次删除测试,并在内部您的循环中使用$addRow
函数:
$addRow(array(
'ref' => $value['ref'],
'lat' => $key['latitude'],
'long' => $key['longitude'],
'route' => $value['route'],
'locality' => $value['locality'],
'administrative_area_level_2' => $value['administrative_area_level_2'],
'administrative_area_level_1' => $value['administrative_area_level_1'],
'country' => $value['country'],
'postal_code_prefix' => $value['postal_code_prefix'],
'postal_town' => $value['postal_town'],
'postal_code' => $value['postal_code'],
'administrative_area_level_3' => $value['administrative_area_level_3'],
'street_number' => $value['street_number'],
'establishment' => $value['establishment'],
));
从技术上讲,你可以删除string-array-keys,但是我保留了它们,这样你就可以更好地找到你需要更改代码的地方,因为数组已存在。
在完成这项工作之后,您可以安全地删除所有不再需要的临时数组和计数器。
完整用法示例(测试):
require_once 'Classes/PHPExcel.php'; /* PHPExcel <http://phpexcel.codeplex.com/> */
$headers = array(
'ref', 'lat', 'long', 'route', 'locality', 'administrative_area_level_2',
'administrative_area_level_1', 'country', 'postal_code_prefix',
'postal_town', 'postal_code', 'administrative_area_level_3',
'street_number', 'establishment',
);
$addRowCreate = function(PHPExcel_Worksheet $sheet, $col = 'A', $row = NULL) {
return function(array $data) use ($sheet, $col, &$row) {
if ($row === NULL) {
$row = $sheet->getHighestRow() + 1;
}
$sheet->fromArray(array($data), NULL, "$col$row");
$row++;
};
};
$doc = new PHPExcel();
$doc->getProperties()->setCreator("Anon")
->setLastModifiedBy("Anon")
->setTitle("Crawler Data");
$sheet = $doc->setActiveSheetIndex(0);
$sheet->fromArray($headers);
$addRow = $addRowCreate($sheet);
$addRow($headers);
$writer = PHPExcel_IOFactory::createWriter($doc, 'Excel5');
$writer->save(basename(__FILE__, '.php') . '.xls');
die('test finished.');
旧答案:
但是,这只会将标题放在excel文件中,而不是数组中的数据。我做错了什么?
实际上,您只是将标题存储到文件中。您不存储任何数据。
我怎样才能让它发挥作用?
以正确的格式显示数组并取消注释代码中的以下行:
//$objPHPExcel->getActiveSheet()->fromArray($sortedData, null, 'A2');
注意$sortedData
是所需的2D数组,see the examples in this dicsussion:
Array
(
[0] => Array
(
[0] => Relative CellA1
[1] => Relative CellB1
[2] => Relative CellC1
)
[1] => Array
(
[0] => Relative CellA2
[1] => Relative CellB2
[2] => Relative CellC2
)
)
除非您没有将数组转换为那种类型的2D格式,否则该功能对您不利。
如果您还有其他问题,请与我们联系。
答案 1 :(得分:-1)
PHPExcel将数据写入单元格,您必须定义它的位置。就像那样你定义标题。原则是您逐行填写文档。 所以我编写示例代码来显示想法
$alphas = range('A', 'Z'); // A, B, C, D, E...
$sheet = $excel->getActiveSheet();
//headers
$sheet
->setCellValue($alphas[0].'1', 'Title1')
->setCellValue($alphas[1].'1', 'Title2')
->setCellValue($alphas[2].'1', 'Title3')
->setCellValue($alphas[3].'1', 'Title4')
;
$sheet->getColumnDimension($alphas[0])->setWidth(40);
$sheet->getColumnDimension($alphas[1])->setWidth(9);
$sheet->getColumnDimension($alphas[2])->setWidth(60);
$sheet->getColumnDimension($alphas[3])->setWidth(30);
$items = ...;// <--- your data
$row_num = 2; // start from 2 row
foreach($items as $item) {
$sheet->setCellValue($alphas[0].$row_num, $item['key1']);
$sheet->setCellValue($alphas[1].$row_num, $item['key2']);
$sheet->setCellValue($alphas[2].$row_num, $item['key3']);
$sheet->setCellValue($alphas[3].$row_num, $item['key4']);
$row_num++;
}
答案 2 :(得分:-1)
您可以创建一个通用函数来从任何2D数组中获取excel内容。
PHP array2xlsx函数
/**
* This function returns xlsx content from an associative array.
*
* Warning: one cell = about 1k memory, so this function does not work
* if your array is too large.
*
* @param array $array
* @param string $title
* @param string $author
* @return string
*/
function array2xlsx(array &$array, $title = 'New Document', $author = null)
{
// Basic checks
if (count($array) == 0)
{
return null;
}
// Putting meta-data into a new excel file
$ex = new PHPExcel();
$ex->getProperties()->setLastModifiedBy($title);
$ex->getProperties()->setTitle($title);
$ex->getProperties()->setSubject($title);
$ex->getProperties()->setDescription($title);
$ex->getProperties()->setCreator($author);
// Select first page on the excel document
$ex->setActiveSheetIndex(0);
$sheet = $ex->getActiveSheet();
// Writes column titles on row 1 (assuming column names are array keys)
$column_names = array_keys(reset($array));
foreach ($column_names as $column_number => $column_name)
{
$azNumber = PHPExcel_Cell::stringFromColumnIndex($column_number);
$sheet->SetCellValue($azNumber . "1", $column_name);
}
// Writes document content
foreach ($array as $row_number => $row)
{
foreach (array_values($row) as $column_number => $cell_content)
{
// Converts column numbers to alphabetic numbering
$azNumber = PHPExcel_Cell::stringFromColumnIndex($column_number);
$sheet->SetCellValue($azNumber . ($row_number + 2), $cell_content);
}
}
// Creates file contents
$writer = new PHPExcel_Writer_Excel2007($ex);
ob_start();
$writer->save("php://output");
$content = ob_get_contents();
ob_end_clean();
return $content;
}
通过发送正确的标题将其直接发送给您的用户。
PHP download_send_header function
function download_send_headers($filename) {
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Disposition: attachment;filename={$filename}");
header("Content-Transfer-Encoding: binary");
}
PHP 用法示例
// We simulate your array
$array = array();
for ($i = 0; ($i < 50); $i++)
{
$array[$i] = array(
'ref' => "ref {$i}",
'lat' => "lat {$i}",
'long' => "long {$i}",
'route' => "route {$i}",
'locality' => "locality {$i}",
'administrative_area_level_2' => "administrative area level 2 {$i}",
'administrative_area_level_1' => "administrative area level 1 {$i}",
'country' => "country {$i}",
'postal_code_prefix' => "postal_code_prefix {$i}",
'postal_town' => "postal_town {$i}",
'postal_code' => "postal code {$i}",
'administrative_area_level_3' => "administrative area level 3 {$i}",
'street_number' => "street number {$i}",
'establishment' => "establishment {$i}",
);
}
// We send headers and excel content from your array
download_send_headers("my_test.xlsx");
echo array2xlsx($array);
结果