View source
<?php
function _sheetnode_phpexcel_export($format, $node) {
require_once drupal_get_path('module', 'sheetnode') . '/socialcalc.inc';
if (empty($node)) {
return drupal_not_found();
}
$sheets = array();
if ($node->type == 'sheetnode') {
$sheets[$node->title] = socialcalc_parse($node->sheetnode['value']);
}
$sheetfields = sheetnode_get_sheetfields($node->type);
if (!empty($sheetfields)) {
foreach ($sheetfields as $sheetfield) {
foreach ($node->{$sheetfield['field_name']} as $delta => $item) {
$sheets[$sheetfield['widget']['label'] . ' ' . ($delta + 1)] = socialcalc_parse($item['value']);
}
}
}
if (empty($sheets)) {
return drupal_not_found();
}
sheetnode_phpexcel_batch_export($sheets, $node->title, $format);
}
function _sheetnode_phpexcel_batch_export_sheet($title, $socialcalc, $filename, $format, $destination, &$context) {
require_once variable_get('sheetnode_phpexcel_library_path', '') . '/Classes/PHPExcel.php';
if (empty($context['results']['workbook'])) {
$workbook = $context['results']['workbook'] = new PHPExcel();
$worksheet = $workbook
->getActiveSheet();
$context['results'] += array(
'filename' => $filename,
'format' => $format,
'destination' => $destination,
);
}
else {
$workbook = $context['results']['workbook'];
$worksheet = $workbook
->createSheet($workbook
->getSheetCount());
}
_sheetnode_phpexcel_export_sheet($worksheet, $title, $socialcalc);
$context['message'] = t('Processed sheet %sheet.', array(
'%sheet' => $worksheet
->getTitle(),
));
}
function _sheetnode_phpexcel_batch_export_finished($success, $results, $operations) {
require_once variable_get('sheetnode_phpexcel_library_path', '') . '/Classes/PHPExcel.php';
@set_time_limit(0);
if ($success) {
PHPExcel_Settings::setPdfRenderer(PHPExcel_Settings::PDF_RENDERER_TCPDF, variable_get('sheetnode_phpexcel_pdf_renderer_path', ''));
$plugins = sheetnode_phpexcel_get_plugins();
$plugin = $plugins[$results['format']];
$writer = PHPExcel_IOFactory::createWriter($results['workbook'], $plugin['php-excel-type']);
$tempname = tempnam(file_directory_temp(), 'sheetnode_phpexcel_');
$writer
->save($tempname);
$_SESSION['sheetnode_phpexcel_download'] = array(
'tempname' => $tempname,
'filename' => _sheetnode_phpexcel_sanitize_filename($results['filename']) . '.' . $results['format'],
'format' => $results['format'],
'destination' => $results['destination'],
);
}
}
function sheetnode_phpexcel_preprocess_sheetnode_phpexcel_export_ready(&$vars) {
if (empty($_SESSION['sheetnode_phpexcel_download'])) {
drupal_not_found();
}
$download = $_SESSION['sheetnode_phpexcel_download'];
$vars['download'] = url('sheetnode/export/download');
$vars['filename'] = $download['filename'];
$vars['destination'] = $download['destination'];
drupal_set_html_head('<meta http-equiv="refresh" content="3;url=' . check_plain($vars['download']) . '" />');
}
function _sheetnode_phpexcel_export_download() {
if (empty($_SESSION['sheetnode_phpexcel_download'])) {
drupal_not_found();
}
$download = $_SESSION['sheetnode_phpexcel_download'];
$plugins = sheetnode_phpexcel_get_plugins();
$plugin = $plugins[$download['format']];
$headers = array(
'Content-Type: ' . $plugin['content-type'],
'Content-Disposition: attachment; filename="' . $download['filename'] . '"',
'Cache-Control: max-age=0',
);
file_transfer($download['tempname'], $headers);
}
function _sheetnode_phpexcel_export_sheet($worksheet, $title, $socialcalc) {
require_once drupal_get_path('module', 'sheetnode') . '/socialcalc.inc';
@set_time_limit(0);
$sc = $socialcalc['sheet'];
$workbook = $worksheet
->getParent();
try {
$worksheet
->SetTitle($title);
} catch (Exception $e) {
watchdog('sheetnode_phpexcel', 'Error setting worksheet title to "!title": @error', array(
'!title' => $title,
'@error' => $e
->getMessage(),
), WATCHDOG_WARNING);
}
if (!empty($sc['names'])) {
foreach ($sc['names'] as $name => $info) {
$definition = ltrim($info['definition'], '=');
@(list($sheetname, $reference) = explode('!', $definition, 2));
if (empty($reference)) {
$reference = $definition;
$external = $worksheet;
}
else {
$sheetname = trim($sheetname, '"\'');
list($value, $title2) = sheetnode_find_sheet($sheetname);
if ($value) {
$external = $workbook
->getSheetByName($title2);
if (!$external) {
$external = $workbook
->createSheet($workbook
->getSheetCount());
$socialcalc2 = socialcalc_parse($value);
_sheetnode_phpexcel_export_sheet($external, $title2, $socialcalc2);
}
}
}
try {
$range = PHPExcel_Cell::rangeBoundaries($reference);
} catch (Exception $e) {
watchdog('sheetnode_phpexcel', 'Could not export name %name with value %definition because non-range names are not yet supported.', array(
'%name' => $name,
'%definition' => $definition,
));
continue;
}
if (!empty($external)) {
$workbook
->addNamedRange(new PHPExcel_NamedRange($name, $external, $reference));
}
else {
watchdog('sheetnode_phpexcel', 'Could not export name %name with value %definition because %sheetname was not found.', array(
'%name' => $name,
'%definition' => $definition,
'%sheetname' => $sheetname,
));
}
}
}
if ($sc['cells']) {
foreach ($sc['cells'] as $coord => $c) {
static $styles = array();
$hash = _sheetnode_phpexcel_export_get_style_hash($c);
if (empty($styles[$hash])) {
$styles[$hash] = $style = new PHPExcel_Style();
}
else {
$style = NULL;
}
_sheetnode_phpexcel_export_cell_value_and_format($c, $coord, $sc, $worksheet, $style);
if (!empty($c['comment'])) {
$worksheet
->getComment($coord)
->getText()
->createTextRun($c['comment']);
}
if (!empty($style)) {
$font = $style
->getFont();
if (!empty($c['font'])) {
$scf = socialcalc_cellformat_parsefont($c, $sc);
if (!empty($scf['family'])) {
$font
->setName($scf['family']);
}
if (!empty($scf['size'])) {
$font
->setSize(floatval($scf['size']));
}
if (!empty($scf['bold'])) {
$font
->setBold(true);
}
if (!empty($scf['italic'])) {
$font
->setItalic(true);
}
}
if (!empty($c['color'])) {
$scc = socialcalc_cellformat_parsecolor($c, $sc, 'color');
$rgb = sprintf('%02X%02X%02X', $scc['r'], $scc['g'], $scc['b']);
$font
->getColor()
->setRGB($rgb);
}
foreach (array(
'br' => 'getRight',
'bl' => 'getLeft',
'bt' => 'getTop',
'bb' => 'getBottom',
) as $pos => $method) {
$border = socialcalc_cellformat_parseborder($c, $sc, $pos);
if (empty($border)) {
continue;
}
$borderobj = $style
->getBorders()
->{$method}();
$thickness = str_replace('px', '', $border['thickness']);
if ($thickness > 0 && $thickness < 7) {
$thickness = 'thin';
}
else {
if ($thickness > 7 && $thickness < 15) {
$thickness = 'medium';
}
else {
if ($thickness > 15) {
$thickness = 'thick';
}
}
}
$borderstyles = array(
'thin' => array(
'solid' => PHPExcel_Style_Border::BORDER_THIN,
'dashed' => PHPExcel_Style_Border::BORDER_DASHED,
'dotted' => PHPExcel_Style_Border::BORDER_DOTTED,
'double' => PHPExcel_Style_Border::BORDER_DOUBLE,
),
'medium' => array(
'solid' => PHPExcel_Style_Border::BORDER_MEDIUM,
'dashed' => PHPExcel_Style_Border::BORDER_MEDIUMDASHED,
),
'thick' => array(
'solid' => PHPExcel_Style_Border::BORDER_THICK,
),
);
$borderstyle = isset($borderstyles[$thickness][$border['style']]) ? $borderstyles[$thickness][$border['style']] : PHPExcel_Style_Border::BORDER_THIN;
$borderobj
->setBorderStyle($borderstyle);
$scc = $border['color'];
$rgb = sprintf('%02X%02X%02X', $scc['r'], $scc['g'], $scc['b']);
$borderobj
->getColor()
->setRGB($rgb);
}
if (!empty($c['bgcolor'])) {
$scc = socialcalc_cellformat_parsecolor($c, $sc, 'bgcolor');
$rgb = sprintf('%02X%02X%02X', $scc['r'], $scc['g'], $scc['b']);
$style
->getFill()
->setFillType(PHPExcel_Style_Fill::FILL_SOLID);
$style
->getFill()
->getStartColor()
->setRGB($rgb);
}
if (!empty($c['cellformat'])) {
$alignments = array(
'left' => PHPExcel_Style_Alignment::HORIZONTAL_LEFT,
'right' => PHPExcel_Style_Alignment::HORIZONTAL_RIGHT,
'center' => PHPExcel_Style_Alignment::HORIZONTAL_CENTER,
);
$alignment = isset($alignments[$sc['cellformats'][$c['cellformat']]]) ? $alignments[$sc['cellformats'][$c['cellformat']]] : NULL;
if ($alignment) {
$style
->getAlignment()
->setHorizontal($alignment);
}
}
$layout = socialcalc_cellformat_parselayout($c, $sc);
if (!empty($layout['alignvert'])) {
$valignments = array(
'top' => PHPExcel_Style_Alignment::VERTICAL_TOP,
'bottom' => PHPExcel_Style_Alignment::VERTICAL_BOTTOM,
'middle' => PHPExcel_Style_Alignment::VERTICAL_CENTER,
);
$valignment = isset($valignments[$layout['alignvert']]) ? $valignments[$layout['alignvert']] : NULL;
if ($valignment) {
$style
->getAlignment()
->setVertical($valignment);
}
}
}
$worksheet
->duplicateStyle($styles[$hash], $coord);
if (@$c['colspan'] > 1 || @$c['rowspan'] > 1) {
$coord2 = socialcalc_cr_to_coord($c['pos'][0] + max(@$c['colspan'] - 1, 0), $c['pos'][1] + max(@$c['rowspan'] - 1, 0));
$worksheet
->mergeCells($coord . ':' . $coord2);
}
}
}
$font = $worksheet
->getDefaultStyle()
->getFont();
if (!empty($sc['colattribs']['width'])) {
foreach ($sc['colattribs']['width'] as $c => $width) {
$worksheet
->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($c - 1))
->setWidth(PHPExcel_Shared_Drawing::pixelsToCellDimension($width, $font));
}
}
if (!empty($sc['rowattribs']['height'])) {
foreach ($sc['rowattribs']['height'] as $r => $height) {
$worksheet
->getRowDimension($r)
->setRowHeight($height);
}
}
foreach ($worksheet
->getCellCollection() as $cellID) {
$cell = $worksheet
->getCell($cellID);
if ($cell
->getDatatype() == PHPExcel_Cell_DataType::TYPE_FORMULA) {
try {
$cell
->getCalculatedValue();
} catch (Exception $e) {
$coord = $cell
->getCoordinate();
$cell
->setValue($sc['cells'][$coord]['datavalue']);
$comment = t(variable_get('sheetnode_phpexcel_bad_formula', 'Could not export formula !formula.'), array(
'!formula' => $sc['cells'][$coord]['formula'],
));
$worksheet
->getComment($coord)
->getText()
->createTextRun($comment);
}
}
}
unset($styles);
}
function _sheetnode_phpexcel_export_get_style_hash($c) {
$styles = array();
foreach (array(
'font',
'color',
'bgcolor',
'cellformat',
'alignvert',
'bt',
'bb',
'bl',
'br',
'nontextvalueformat',
) as $attrib) {
if (!empty($c[$attrib])) {
$styles[] = $attrib . ':' . $c[$attrib];
}
}
return md5(implode(',', $styles));
}
function _sheetnode_phpexcel_export_cell_value_and_format($c, $coord, $sc, $worksheet, $style) {
$cell = $worksheet
->getCell($coord);
$valuetype = empty($c['valuetype']) ? NULL : substr($c['valuetype'], 0, 1);
$valuesubtype = empty($c['valuetype']) ? NULL : substr($c['valuetype'], 1);
$displayvalue = @$c['datavalue'];
$valueformat = NULL;
if (!empty($c['errors']) || $valuetype == 'e') {
$displayvalue = !empty($c['errors']) ? $c['errors'] : (!empty($valuesubtype) ? $valuesubtype : t('Unknown error'));
$cell
->setValueExplicit($displayvalue, PHPExcel_Cell_DataType::TYPE_ERROR);
}
else {
if ($valuetype == 't') {
$valueformat = !empty($c['textvalueformat']) ? $sc['valueformats'][$c['textvalueformat']] : (!empty($sc['defaulttextvalueformat']) ? $sc['valueformats'][$sc['defaulttextvalueformat']] : NULL);
if (in_array(strtolower($valueformat), array(
'auto',
'none',
'general',
))) {
$valueformat = NULL;
}
if (empty($valueformat)) {
switch ($valuesubtype) {
case 'h':
$valueformat = 'text-html';
break;
case 'w':
case 'r':
$valueformat = 'text-wiki';
break;
case 'l':
$valueformat = 'text-link';
break;
default:
$valueformat = 'text-plain';
break;
}
}
if ($c['datatype'] == 'f') {
if (strpos($c['formula'], '!') !== FALSE) {
_sheetnode_phpexcel_export_reference($c, $cell, $worksheet);
}
else {
$cell
->setValue('=' . $c['formula']);
}
}
else {
switch ($valueformat) {
case 'text-plain':
$cell
->setValueExplicit($displayvalue, PHPExcel_Cell_DataType::TYPE_STRING);
break;
case 'text-html':
require_once drupal_get_path('module', 'sheetnode_phpexcel') . '/html2richtext.inc';
$html2rtf = new Sheetnode_PHPExcel_HTML2RichText($displayvalue);
$rtf = $html2rtf
->convert($cell);
if ($rtf) {
$cell
->setValue($rtf);
}
else {
$stripped = preg_replace('/^\\s+|\\s+$/', '', strip_tags($displayvalue));
$cell
->setValueExplicit($stripped, PHPExcel_Cell_DataType::TYPE_STRING);
}
break;
case 'text-url':
case 'text-link':
$matches = array();
if (preg_match('/^(.*)<(.*)>$/', $displayvalue, $matches)) {
$text = trim($matches[1], "\r\n\t \"");
$url = $matches[2];
}
else {
$url = $displayvalue;
$parse_url = parse_url($url);
$text = $parse_url['host'] . $parse_url['path'];
}
$cell
->setValueExplicit($text, PHPExcel_Cell_DataType::TYPE_STRING);
$cell
->getHyperlink()
->setUrl($url);
break;
case 'text-wiki':
break;
case 'text-image':
if (function_exists('curl_init')) {
$ch = curl_init($displayvalue);
$filename = tempnam(file_directory_temp(), 'sheetnode_phpexcel_');
$fp = fopen($filename, 'wb');
$options = array(
CURLOPT_FILE => $fp,
CURLOPT_HEADER => 0,
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_TIMEOUT => 60,
);
curl_setopt_array($ch, $options);
curl_exec($ch);
curl_close($ch);
fclose($fp);
$image_info = image_get_info($filename);
if (!empty($image_info)) {
$objDrawing = new PHPExcel_Worksheet_Drawing();
$objDrawing
->setPath($filename);
$objDrawing
->setCoordinates($coord);
$objDrawing
->setWidth($image_info['width']);
$objDrawing
->setWorksheet($worksheet);
}
}
break;
case 'hidden':
break;
case 'formula':
break;
default:
if (substr($valueformat, 0, 12) == 'text-custom:') {
}
else {
if (substr($valueformat, 0, 6) == 'custom') {
}
else {
$cell
->setValue($displayvalue);
}
}
break;
}
}
}
else {
if ($valuetype == 'n') {
$valueformat = !empty($c['nontextvalueformat']) ? $sc['valueformats'][$c['nontextvalueformat']] : (!empty($sc['defaultnontextvalueformat']) ? $sc['valueformats'][$sc['defaultnontextvalueformat']] : NULL);
if (in_array(strtolower($valueformat), array(
'auto',
'none',
))) {
$valueformat = NULL;
}
if (empty($valueformat)) {
switch ($valuesubtype) {
case '%':
$valueformat = SocialCalc_Constants::$defaultFormatp;
break;
case '$':
$valueformat = SocialCalc_Constants::$defaultFormatc;
break;
case 'dt':
$valueformat = SocialCalc_Constants::$defaultFormatdt;
break;
case 'd':
$valueformat = SocialCalc_Constants::$defaultFormatd;
break;
case 't':
$valueformat = SocialCalc_Constants::$defaultFormatt;
break;
case 'l':
$valueformat = 'logical';
break;
default:
$valueformat = PHPExcel_Style_NumberFormat::FORMAT_GENERAL;
break;
}
}
if ($c['datatype'] == 'f') {
if (strpos($c['formula'], '!') !== FALSE) {
_sheetnode_phpexcel_export_reference($c, $cell, $worksheet);
}
else {
$cell
->setValue('=' . $c['formula']);
}
}
else {
if ($valueformat == 'logical') {
$displayvalue = empty($displayvalue) ? SocialCalc_Constants::$defaultDisplayFALSE : SocialCalc_Constants::$defaultDisplayTRUE;
$cell
->setValue($displayvalue);
$valueformat = NULL;
}
else {
if ($valueformat == 'formula') {
$cell
->setValueExplicit('=' . $c['formula'], PHPExcel_Cell_DataType::TYPE_STRING);
}
else {
if ($valueformat == 'forcetext') {
$cell
->setValueExplicit($displayvalue, PHPExcel_Cell_DataType::TYPE_STRING);
}
else {
$cell
->setValueExplicit($displayvalue, PHPExcel_Cell_DataType::TYPE_NUMERIC);
}
}
}
}
if ($valueformat == 'hidden') {
}
else {
if (!empty($valueformat) && !empty($style)) {
$style
->getNumberFormat()
->setFormatCode($valueformat);
}
}
}
else {
$cell
->setValueExplicit('', PHPExcel_Cell_DataType::TYPE_NULL);
}
}
}
}
function _sheetnode_phpexcel_export_reference($c, $cell, $worksheet) {
list($sheetname, $reference) = explode('!', $c['formula'], 2);
$sheetname = trim($sheetname, '"\'');
list($value, $title) = sheetnode_find_sheet($sheetname);
if ($value) {
$workbook = $worksheet
->getParent();
$external = $workbook
->getSheetByName($title);
if (!$external) {
$external = $workbook
->createSheet($workbook
->getSheetCount());
$socialcalc = socialcalc_parse($value);
_sheetnode_phpexcel_export_sheet($external, $title, $socialcalc);
}
$cell
->setValue('=\'' . $title . '\'!' . $reference);
}
else {
$cell
->setValue($c['datavalue']);
$comment = t(variable_get('sheetnode_phpexcel_bad_formula', 'Could not export formula !formula.'), array(
'!formula' => $c['formula'],
));
$worksheet
->getComment($cell
->getCoordinate())
->getText()
->createTextRun($comment);
}
}
function sheetnode_phpexcel_sheetnode_phpexcel_html2richtext($run, $cell, $entry, $converter) {
switch ($entry['value']) {
case 'strong':
case 'b':
$run
->getFont()
->setBold(TRUE);
break;
case 'em':
case 'i':
$run
->getFont()
->setItalic(TRUE);
break;
case 'u':
$run
->getFont()
->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE);
break;
case 'strike':
$run
->getFont()
->setStrikethrough(TRUE);
break;
case 'sub':
$run
->getFont()
->setSubScript(TRUE);
break;
case 'sup':
$run
->getFont()
->setSuperScript(TRUE);
break;
case 'a':
if (!empty($entry['attribute']['href'])) {
$cell
->getHyperlink()
->setUrl($entry['attribute']['href']);
}
break;
}
if (!empty($entry['style'])) {
foreach ($entry['style'] as $key => $value) {
switch ($key) {
case 'color':
$color = $converter
->convertHTMLColorToDec($value);
$rgb = sprintf('%02X%02X%02X', $color['R'], $color['G'], $color['B']);
$run
->getFont()
->getColor()
->setRGB($rgb);
break;
case 'font-family':
$run
->getFont()
->setName($value);
break;
case 'font-size':
$run
->getFont()
->setSize($converter
->getHTMLUnitToUnits($value, 1, 'pt', TRUE));
break;
case 'font-style':
switch ($value) {
case 'italic':
$run
->getFont()
->setItalic(TRUE);
break;
}
break;
case 'text-decoration':
switch ($value) {
case 'underline':
$run
->getFont()
->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE);
break;
}
break;
case 'font-weight':
if ($value == 'bold' || $value == 'bolder' || $value >= 700) {
$run
->getFont()
->setBold(TRUE);
}
break;
case 'background-color':
break;
}
}
}
}