Magento 1.x的Export功能可以很方便地对Customers的数据进行导出,但是存在几个不足(或者说不方便)的地方:
1. 默认导出的 .CSV文件是以UTF-8格式编码的,而MS Excle的默认编码格式是Unicode,所以导出的 .CSV文件直接在Excle中打开时中文会乱码,乱码不仅会导致中文单元格无法阅读,别且会影响其它单元格,会使其它单元格错位
2. 缺少is_subscribed的信息。is_subscribed是用来标识一个Customer是否愿意接收订阅消息(Newsletter),这个信息经常会用到,但很可惜Export无法导出is_subscribed信息,因为is_subscribed信息保存在Newsletter表,没有直接保存在与Customer相关的表中。
3. 虽然Export页面可以选择Skip一些不需要的信息项,但是有一些不需要的信息项没有列出,所以有一些不需要的信息无法筛掉。
上面列出的3个不足:
其中第1条是可以通过文件转码的方式解决的,不需要修改code,而且修改code会比较复杂,因为涉及到生成 .CVS文件。具体做法是用txt打开下载好的.CVS文件,然后选择“另存为”,在“另存为”对话框的下方,会有选择编码格式的下拉菜单,将编码格式从UTF-8改为Unicode,然后保存即可解决乱码问题。
第2条和第3条是需要修改code才能解决的。首先来看一下Magento Default是如何实现的:
在后台的Export页面,通过Form的action(index.php/admin/export/export/key/......./)可以知道,Export请求是在一个名叫Export的Controller中的exportAction中完成的。
通过在IDE中搜索ExportController.php这个文件名可以很快定位代码位置,主要的工作是在以下这两个代码片段中完成的:
按 Ctrl+C 复制代码
/**
* Load data with filter applying and create file for download.
*
* @return Mage_ImportExport_Adminhtml_ExportController
*/
public function exportAction()
{
if ($this->getRequest()->getPost(Mage_ImportExport_Model_Export::FILTER_ELEMENT_GROUP)) {
try {
/** @var $model Mage_ImportExport_Model_Export */
$model = Mage::getModel('importexport/export');
$model->setData($this->getRequest()->getParams());
return $this->_prepareDownloadResponse(
$model->getFileName(),
$model->export(),
$model->getContentType()
);
} catch (Mage_Core_Exception $e) {
$this->_getSession()->addError($e->getMessage());
} catch (Exception $e) {
Mage::logException($e);
$this->_getSession()->addError($this->__('No valid data sent'));
}
} else {
$this->_getSession()->addError($this->__('No valid data sent'));
}
return $this->_redirect('*/*/index');
}
按 Ctrl+C 复制代码
按 Ctrl+C 复制代码
/**
* Declare headers and content file in response for file download
*
* @param string $fileName
* @param string|array $content set to null to avoid starting output, $contentLength should be set explicitly in
* that case
* @param string $contentType
* @param int $contentLength explicit content length, if strlen($content) isn't applicable
* @return Mage_Core_Controller_Varien_Action
*/
protected function _prepareDownloadResponse(
$fileName,
$content,
$contentType = 'application/octet-stream',
$contentLength = null)
{
$session = Mage::getSingleton('admin/session');
if ($session->isFirstPageAfterLogin()) {
$this->_redirect($session->getUser()->getStartupPageUrl());
return $this;
}
$isFile = false;
$file = null;
if (is_array($content)) {
if (!isset($content['type']) || !isset($content['value'])) {
return $this;
}
if ($content['type'] == 'filename') {
$isFile = true;
$file = $content['value'];
$contentLength = filesize($file);
}
}
$this->getResponse()
->setHttpResponseCode(200)
->setHeader('Pragma', 'public', true)
->setHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0', true)
->setHeader('Content-type', $contentType, true)
->setHeader('Content-Length', is_null($contentLength) ? strlen($content) : $contentLength, true)
->setHeader('Content-Disposition', 'attachment; filename="'.$fileName.'"', true)
->setHeader('Last-Modified', date('r'), true);
if (!is_null($content)) {
if ($isFile) {
$this->getResponse()->clearBody();
$this->getResponse()->sendHeaders();
$ioAdapter = new Varien_Io_File();
$ioAdapter->open(array('path' => $ioAdapter->dirname($file)));
$ioAdapter->streamOpen($file, 'r');
while ($buffer = $ioAdapter->streamRead()) {
print $buffer;
}
$ioAdapter->streamClose();
if (!empty($content['rm'])) {
$ioAdapter->rm($file);
}
exit(0);
} else {
$this->getResponse()->setBody($content);
}
}
return $this;
}
按 Ctrl+C 复制代码
_prepareDownloadResponse($fileName, $content, $contentType = 'application/octet-stream', $contentLength = null)方法是Mage_Core_Controller_Varien_Action 类提供的封装好的方法,它根据参数中提供的文件名、文件内容、文件类型生成一个文件并发送到浏览器,这是一个公用的方法,要修改Export的行为,只需要修改传给它的参数就行了。(责任编辑:好模板) |