Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14047505
D18955.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
9 KB
Referenced Files
None
Subscribers
None
D18955.id.diff
View Options
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -2847,6 +2847,7 @@
'PhabricatorEventListener' => 'infrastructure/events/PhabricatorEventListener.php',
'PhabricatorEventType' => 'infrastructure/events/constant/PhabricatorEventType.php',
'PhabricatorExampleEventListener' => 'infrastructure/events/PhabricatorExampleEventListener.php',
+ 'PhabricatorExcelExportFormat' => 'infrastructure/export/PhabricatorExcelExportFormat.php',
'PhabricatorExecFutureFileUploadSource' => 'applications/files/uploadsource/PhabricatorExecFutureFileUploadSource.php',
'PhabricatorExportEngineExtension' => 'infrastructure/export/PhabricatorExportEngineExtension.php',
'PhabricatorExportField' => 'infrastructure/export/PhabricatorExportField.php',
@@ -8282,6 +8283,7 @@
'PhabricatorEventListener' => 'PhutilEventListener',
'PhabricatorEventType' => 'PhutilEventType',
'PhabricatorExampleEventListener' => 'PhabricatorEventListener',
+ 'PhabricatorExcelExportFormat' => 'PhabricatorExportFormat',
'PhabricatorExecFutureFileUploadSource' => 'PhabricatorFileUploadSource',
'PhabricatorExportEngineExtension' => 'Phobject',
'PhabricatorExportField' => 'Phobject',
diff --git a/src/applications/search/controller/PhabricatorApplicationSearchController.php b/src/applications/search/controller/PhabricatorApplicationSearchController.php
--- a/src/applications/search/controller/PhabricatorApplicationSearchController.php
+++ b/src/applications/search/controller/PhabricatorApplicationSearchController.php
@@ -410,8 +410,10 @@
if ($named_query) {
$filename = $named_query->getQueryName();
+ $sheet_title = $named_query->getQueryName();
} else {
$filename = $engine->getResultTypeDescription();
+ $sheet_title = $engine->getResultTypeDescription();
}
$filename = phutil_utf8_strtolower($filename);
$filename = PhabricatorFile::normalizeFileName($filename);
@@ -445,8 +447,9 @@
$mime_type = $format->getMIMEContentType();
$filename = $filename.'.'.$extension;
- $format = clone $format;
- $format->setViewer($viewer);
+ $format = id(clone $format)
+ ->setViewer($viewer)
+ ->setTitle($sheet_title);
$export_data = $engine->newExport($objects);
$objects = array_values($objects);
diff --git a/src/infrastructure/export/PhabricatorEpochExportField.php b/src/infrastructure/export/PhabricatorEpochExportField.php
--- a/src/infrastructure/export/PhabricatorEpochExportField.php
+++ b/src/infrastructure/export/PhabricatorEpochExportField.php
@@ -24,4 +24,24 @@
return (int)$value;
}
+ public function getPHPExcelValue($value) {
+ $epoch = $this->getNaturalValue($value);
+
+ $seconds_per_day = phutil_units('1 day in seconds');
+ $offset = ($seconds_per_day * 25569);
+
+ return ($epoch + $offset) / $seconds_per_day;
+ }
+
+ /**
+ * @phutil-external-symbol class PHPExcel_Style_NumberFormat
+ */
+ public function formatPHPExcelCell($cell, $style) {
+ $code = PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2;
+
+ $style
+ ->getNumberFormat()
+ ->setFormatCode($code);
+ }
+
}
diff --git a/src/infrastructure/export/PhabricatorExcelExportFormat.php b/src/infrastructure/export/PhabricatorExcelExportFormat.php
new file mode 100644
--- /dev/null
+++ b/src/infrastructure/export/PhabricatorExcelExportFormat.php
@@ -0,0 +1,145 @@
+<?php
+
+final class PhabricatorExcelExportFormat
+ extends PhabricatorExportFormat {
+
+ const EXPORTKEY = 'excel';
+
+ private $workbook;
+ private $sheet;
+ private $rowCursor;
+
+ public function getExportFormatName() {
+ return pht('Excel (.xlsx)');
+ }
+
+ public function isExportFormatEnabled() {
+ return true;
+ }
+
+ public function getFileExtension() {
+ return 'xlsx';
+ }
+
+ public function getMIMEContentType() {
+ return 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
+ }
+
+ /**
+ * @phutil-external-symbol class PHPExcel_Cell_DataType
+ */
+ public function addHeaders(array $fields) {
+ $sheet = $this->getSheet();
+
+ $header_format = array(
+ 'font' => array(
+ 'bold' => true,
+ ),
+ );
+
+ $row = 1;
+ $col = 0;
+ foreach ($fields as $field) {
+ $cell_value = $field->getLabel();
+
+ $cell_name = $this->getCellName($col, $row);
+
+ $cell = $sheet->setCellValue(
+ $cell_name,
+ $cell_value,
+ $return_cell = true);
+
+ $sheet->getStyle($cell_name)->applyFromArray($header_format);
+ $cell->setDataType(PHPExcel_Cell_DataType::TYPE_STRING);
+
+ $width = $field->getCharacterWidth();
+ if ($width !== null) {
+ $col_name = $this->getCellName($col);
+ $sheet->getColumnDimension($col_name)
+ ->setWidth($width);
+ }
+
+ $col++;
+ }
+ }
+
+ public function addObject($object, array $fields, array $map) {
+ $sheet = $this->getSheet();
+
+ $col = 0;
+ foreach ($fields as $key => $field) {
+ $cell_value = $map[$key];
+ $cell_value = $field->getPHPExcelValue($cell_value);
+
+ $cell_name = $this->getCellName($col, $this->rowCursor);
+
+ $cell = $sheet->setCellValue(
+ $cell_name,
+ $cell_value,
+ $return_cell = true);
+
+ $style = $sheet->getStyle($cell_name);
+ $field->formatPHPExcelCell($cell, $style);
+
+ $col++;
+ }
+
+ $this->rowCursor++;
+ }
+
+ /**
+ * @phutil-external-symbol class PHPExcel_IOFactory
+ */
+ public function newFileData() {
+ $workbook = $this->getWorkbook();
+ $writer = PHPExcel_IOFactory::createWriter($workbook, 'Excel2007');
+
+ ob_start();
+ $writer->save('php://output');
+ $data = ob_get_clean();
+
+ return $data;
+ }
+
+ private function getWorkbook() {
+ if (!$this->workbook) {
+ $this->workbook = $this->newWorkbook();
+ }
+ return $this->workbook;
+ }
+
+ /**
+ * @phutil-external-symbol class PHPExcel
+ */
+ private function newWorkbook() {
+ include_once 'PHPExcel.php';
+ return new PHPExcel();
+ }
+
+ private function getSheet() {
+ if (!$this->sheet) {
+ $workbook = $this->getWorkbook();
+
+ $sheet = $workbook->setActiveSheetIndex(0);
+ $sheet->setTitle($this->getTitle());
+
+ $this->sheet = $sheet;
+
+ // The row cursor starts on the second row, after the header row.
+ $this->rowCursor = 2;
+ }
+
+ return $this->sheet;
+ }
+
+ private function getCellName($col, $row = null) {
+ $col_name = chr(ord('A') + $col);
+
+ if ($row === null) {
+ return $col_name;
+ }
+
+ return $col_name.$row;
+ }
+
+}
diff --git a/src/infrastructure/export/PhabricatorExportField.php b/src/infrastructure/export/PhabricatorExportField.php
--- a/src/infrastructure/export/PhabricatorExportField.php
+++ b/src/infrastructure/export/PhabricatorExportField.php
@@ -32,4 +32,19 @@
return $value;
}
+ public function getPHPExcelValue($value) {
+ return $this->getTextValue($value);
+ }
+
+ /**
+ * @phutil-external-symbol class PHPExcel_Cell_DataType
+ */
+ public function formatPHPExcelCell($cell, $style) {
+ $cell->setDataType(PHPExcel_Cell_DataType::TYPE_STRING);
+ }
+
+ public function getCharacterWidth() {
+ return 24;
+ }
+
}
diff --git a/src/infrastructure/export/PhabricatorExportFormat.php b/src/infrastructure/export/PhabricatorExportFormat.php
--- a/src/infrastructure/export/PhabricatorExportFormat.php
+++ b/src/infrastructure/export/PhabricatorExportFormat.php
@@ -4,6 +4,7 @@
extends Phobject {
private $viewer;
+ private $title;
final public function getExportFormatKey() {
return $this->getPhobjectClassConstant('EXPORTKEY');
@@ -18,6 +19,15 @@
return $this->viewer;
}
+ final public function setTitle($title) {
+ $this->title = $title;
+ return $this;
+ }
+
+ final public function getTitle() {
+ return $this->title;
+ }
+
abstract public function getExportFormatName();
abstract public function getMIMEContentType();
abstract public function getFileExtension();
diff --git a/src/infrastructure/export/PhabricatorIDExportField.php b/src/infrastructure/export/PhabricatorIDExportField.php
--- a/src/infrastructure/export/PhabricatorIDExportField.php
+++ b/src/infrastructure/export/PhabricatorIDExportField.php
@@ -7,4 +7,8 @@
return (int)$value;
}
+ public function getCharacterWidth() {
+ return 12;
+ }
+
}
diff --git a/src/infrastructure/export/PhabricatorIntExportField.php b/src/infrastructure/export/PhabricatorIntExportField.php
--- a/src/infrastructure/export/PhabricatorIntExportField.php
+++ b/src/infrastructure/export/PhabricatorIntExportField.php
@@ -4,7 +4,22 @@
extends PhabricatorExportField {
public function getNaturalValue($value) {
+ if ($value === null) {
+ return $value;
+ }
+
return (int)$value;
}
+ /**
+ * @phutil-external-symbol class PHPExcel_Cell_DataType
+ */
+ public function formatPHPExcelCell($cell, $style) {
+ $cell->setDataType(PHPExcel_Cell_DataType::TYPE_NUMERIC);
+ }
+
+ public function getCharacterWidth() {
+ return 8;
+ }
+
}
diff --git a/src/infrastructure/export/PhabricatorPHIDExportField.php b/src/infrastructure/export/PhabricatorPHIDExportField.php
--- a/src/infrastructure/export/PhabricatorPHIDExportField.php
+++ b/src/infrastructure/export/PhabricatorPHIDExportField.php
@@ -1,4 +1,10 @@
<?php
final class PhabricatorPHIDExportField
- extends PhabricatorExportField {}
+ extends PhabricatorExportField {
+
+ public function getCharacterWidth() {
+ return 32;
+ }
+
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Nov 15, 4:06 AM (2 d, 4 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6718501
Default Alt Text
D18955.id.diff (9 KB)
Attached To
Mode
D18955: Support Excel as a data export format
Attached
Detach File
Event Timeline
Log In to Comment