Не удается экспортировать в Excel 2010 student edition через Zend Framework

#zend-framework

#zend-framework

Вопрос:

Я пытаюсь экспортировать данные в ms Excel, у меня есть Office 2010 student edition для моего приложения, следуя сообщению Пабло Викесаhttp://www.pabloviquez.com/2009/08/export-excel-spreadsheets-using-zend-framework /.

Однако я не могу заставить его работать, происходит следующее

1. При вводе отчетов / report / todaysappointmentsreport / format / excel в адресную строку рабочая книга пытается сохранить как excel.xls

2. Когда я открываю файл, Excel выдает мне следующее предупреждение: файл, который вы пытаетесь открыть ‘excel.xls ‘, имеет формат, отличный от указанного расширением файла, перед открытием файла убедитесь, что файл не поврежден и получен из надежного источника.

  1. При открытии файла отображается только код из моего файла todaysappointmentsreport.export.phtml

Кто-нибудь может сказать мне, где я ошибаюсь, поскольку мне нужно заставить это работать.

Я могу убедиться, что запрос работает, и данные отображаются в моем todaysappointmentsreport.phtml-файле на экране. Я также могу проверить, что компонент установлен в pear вместе с компонентом OLE, от которого он зависит.

Мой код контроллера

 class Reports_ReportController extends Zend_Controller_Action 
 { 
  public function init() 
  { 

       // Excel format context 
            $excelConfig = 
            array('excel' => array 
                                            ('suffix'  => 'excel', 
                                                    'headers' => array( 
                                                                                    'Content-type' => 'application/vnd.ms-excel')), 
            ); 

       //initalise context switch 
       $contextSwitch = $this->_helper->contextSwitch(); 

       // Add the new context 
            $contextSwitch->setContexts($excelConfig); 



            // Set the new context to the reports action 
            $contextSwitch->addActionContext('todaysappointmentsreport', 'excel'); 

            $contextSwitch->initContext(); 

} 

 // action to redirect user straight to login page 
 public function preDispatch() 
 { 
   // set admin layout 
  // check if user is authenticated 
  // if not, redirect to login page 
  $url = $this->getRequest()->getRequestUri();           
  if (!Zend_Auth::getInstance()->hasIdentity()) { 
  $session = new Zend_Session_Namespace('petmanager.auth'); 
  $session->requestURL = $url; 
  $this->_redirect('/login'); 
 } 
    } 

 // report to print todays appointments 
 public function todaysappointmentsreportAction() 
 { 
     $t=date('y-m-d'); 
            $q = Doctrine_Query::create()   
                    ->from('PetManager_Model_Groomappointments g') 
        ->leftJoin('g.PetManager_Model_Clients c') 
                    ->leftJoin('g.PetManager_Model_Pets p') 
                    ->leftJoin('g.PetManager_Model_Users u') 
                    ->leftJoin('g.PetManager_Model_Groomservices s') 
                    ->leftJoin('s.PetManager_Model_Groomprocedures r') 
                    ->where('g.gapmtStatus = 1 AND g.gapmtDate = ?',$t) 
                    ->orderBy('g.gapmtSTime,g.gapmtSTime,u.name'); 
                     $result = $q->fetchArray(); 
                     if (count($result) >= 1) { 
                     $this -> view -> records = $result;             
                     } 

}   
  

Мой сегодняшний код appointmentsreport.excel.phtml, как я уже сказал, это то, что появляется в файле Excel, когда я его открываю.

  // Change error reporting for compatibility 
 // Spreadsheet Excel Writter was built using PHP4, 
 // so there's a lot of DEPRECATED notices 
   error_reporting(E_ERROR | E_WARNING | E_PARSE); 

 /** 
 * PEAR package 
 * 
 * @link http://pear.php.net/package/Spreadsheet_Excel_Writer
 * @see PEAR/Spreadsheet/Excel/Writer.php 
 */ 
 require_once 'Spreadsheet/Excel/Writer.php'; 

 // Lets define some custom colors codes 
 define('CUSTOM_DARK_BLUE', 20); 
 define('CUSTOM_BLUE', 21); 
 define('CUSTOM_LIGHT_BLUE', 22); 
 define('CUSTOM_YELLOW', 23); 
 define('CUSTOM_GREEN', 24); 

// First, we create a Workbook 
$workbook = new Spreadsheet_Excel_Writer(); 

 // Add one sheet, called: Users Report 
 $worksheet = amp;$workbook->addWorksheet('Todays Grooming Appointments Report'); 

 // Create the custom colors on our new workbook 
 // This function takes 4 params: 
 //    - Code index [1 to 64] 
 //    - RGB colors (0-255) 
  $workbook->setCustomColor(CUSTOM_DARK_BLUE, 31, 73, 125); 
  $workbook->setCustomColor(CUSTOM_BLUE, 0, 112, 192); 
  $workbook->setCustomColor(CUSTOM_LIGHT_BLUE, 184, 204, 228);  
  $workbook->setCustomColor(CUSTOM_YELLOW, 255, 192, 0); 
  $workbook->setCustomColor(CUSTOM_GREEN, 0, 176, 80); 

  // Lets hide gridlines 
  //$worksheet->hideScreenGridlines(); 

  // Lets create some custom styles 
  $formatHeader = amp;$workbook->addFormat(); 
  $formatHeader = 
  amp;$workbook->addFormat( 
    array('Size'    => 16, 
          'VAlign'  => 'vcenter', 
          'HAlign'  => 'center', 
          'Bold'    => 1, 
          'Color'   => 'white', 
          'FgColor' => CUSTOM_DARK_BLUE)); 

   $formatReportHeader = 
   amp;$workbook->addFormat( 
    array('Size'     => 9, 
          'VAlign'   => 'bottom', 
          'HAlign'   => 'center', 
          'Bold'     => 1, 
          'FgColor'  => CUSTOM_LIGHT_BLUE, 
          'TextWrap' => true)); 

   $formatData = 
    amp;$workbook->addFormat( 
      array( 
        'Size'   => 8, 
        'HAlign' => 'center', 
        'VAlign' => 'vcenter')); 

   /** 
   * First, format the worksheet, adding the headers 
   * and row/columns custom sizes 
   */ 

   // Create a nice header with a dark blue background 
   // The function setRow takes 3 parameters: 
   //    - row index 
   //    - row height 
   //    - Format to apply to row [Optional] 
   $worksheet->setRow(0, 11, $formatHeader); 
   $worksheet->setRow(1, 46, $formatHeader); 
   $worksheet->setRow(2, 11, $formatHeader); 
   $worksheet->setRow(3, 11, $formatHeader); 
   $worksheet->setRow(4, 11, $formatHeader); 

// Set the size of the columns 
// The function setColumn takes 5 params: 
//     - First column 
//     - Last column 
//     - Column Width 
//     - Format [Optional, default = 0] 
//     - Hidden [Optional, default = 0] 
 $worksheet->setColumn(0, 0, 7); //  shrink it to 7 
 $worksheet->setColumn(1, 1, 12); // set the width to 12 
 $worksheet->setColumn(1, 1, 15); // set the width to 15 
 $worksheet->setColumn(1, 1, 15); // set the width to 15 
 $worksheet->setColumn(1, 1, 15); // set the width to 15 

/** 
* 
* Once we have the format ready, add the text to the spreadsheet 
* 
*/ 
// Write a text header 
$worksheet->write(1, 1, 'Todays Grooming Appointments Report', $formatHeader); 

 // Create the header for the data starting @ row 6
 $indexCol = 0; 
 $indexRow = 6; 
 $worksheet->write($indexRow, $indexCol  , 'Scheduled Time', $formatReportHeader); 
 $worksheet->write($indexRow, $indexCol  , 'Client', $formatReportHeader); 
 $worksheet->write($indexRow, $indexCol  , 'Pet', $formatReportHeader); 
 $worksheet->write($indexRow, $indexCol  , 'Procedure', $formatReportHeader); 
 $worksheet->write($indexRow, $indexCol  , 'Groomer', $formatReportHeader); 

 $indexRow  ;   // Advance to the next row 
 $indexCol = 0; // Start @ column 0 

 // Print the report data 
 if(count($this->records) == 0) { 
  // No data 
  $worksheet->write( 
    $indexRow, 
    $indexCol, 
    'No Appointments', 
    $formatData); 

 } else { 
  // Write the data 
   foreach ($this->records as $r) { 
    $worksheet->write( 
        $indexRow, 
        $indexCol  , 
        $this->$r['gapmtSTime'] - $this->substr$r['gapmtETime'], 
        $formatData); 

    $worksheet->write( 
        $indexRow, 
        $indexCol  , 
        $this->$r['PetManager_Model_Clients']['firstName'] $this->$r ['PetManager_Model_Clients']['lastName'], 
        $formatData); 

    $worksheet->write( 
        $indexRow, 
        $indexCol  , 
        $this->$r['PetManager_Model_Pets']['name'], 
        $formatData); 

        $worksheet->write( 
        $indexRow, 
        $indexCol  , 
        $this->$r['PetManager_Model_Groomservices']['PetManager_Model_Groomprocedures']['groomprocedure'], 
        $formatData); 

            $worksheet->write( 
        $indexRow, 
        $indexCol  , 
        $this->$r['PetManager_Model_Users']['name'], 
        $formatData);   

    // Advance to the next row 
     $indexRow  ; 
  } 
 } 

 /** 
 * 
 * Response with the excel file 
 * 
 */ 

 // Sends HTTP headers for the Excel file. 
 $workbook->send('todaysappointmentsreport.xls'); 

// Calls finalization methods. 
// This method should always be the last one to be called on every workbook 
$workbook->close();
  

Комментарии:

1. У меня также была эта проблема, после чего я перешел на PHPExcel ( phpexcel.codeplex.com ). На мой взгляд, эта библиотека намного лучше, чем Spreadsheet_Excel_Writer…

Ответ №1:

Убедитесь, что содержимое вашего файла представления «todaysappointmentsreport.excel.phtml» заключено в открывающие и закрывающие теги php.

Ответ №2:

 public function indexAction()
{
    $this->filename = "/excel-" . date( "m-d-Y" ) . "-".mt_rand(10000,20000).".xls";

    $realPath = realpath($this->filename);
    if (false === $realPath )
    {
        touch($this->filename);
        chmod($this->filename, 0777); 
    }

    $this->filename = realpath( $this->filename );
    $this->handle = fopen( $this->filename, "w" );

    $projectsModul = new Model_DbTable_Projects();
    $projects = $projectsModul->fetchProjects();

    foreach ($projects->toArray() as $row)
    {
        $this->finalData[] = array(
            $row['id'],
            $row['company'],
            $row['project'],
            $row['start'],
            $row['end']
        );
    }

    foreach ( $this->finalData AS $finalRow )
    {
        fputcsv( $this->handle, $finalRow, "t" );
    }

    fclose( $this->handle );

    $this->_helper->layout->disableLayout();
    $this->_helper->viewRenderer->setNoRender();

    $this->getResponse()->setRawHeader( "Content-Type: application/vnd.ms-excel; charset=UTF-8")
        ->setRawHeader("Content-Disposition: attachment; filename=excel.xls")
        ->setRawHeader("Content-Transfer-Encoding: binary")
        ->setRawHeader("Expires: 0")
        ->setRawHeader("Cache-Control: must-revalidate, post-check=0, pre-check=0")
        ->setRawHeader("Pragma: public")
        ->setRawHeader("Content-Length: " . filesize($this->filename))
        ->sendResponse();

    readfile($this->filename); 
    exit();
}
  

Ответ №3:

Я работаю над аналогичным примером для своего собственного проекта, поэтому, если я обнаружу решение, я обновлю этот поток любыми результатами.

Здесь есть полезная статья о помощнике просмотра contextSwitch (maltblue), в которой более подробно объясняется помощник.

помощник для просмотра контекстного переключения

В конце концов мне удалось экспортировать в csv ok, поместив заголовки непосредственно в действие контроллера следующим образом.

в моем действии…

 //create the csv file header and filename based on the action name
    $actionName = $this->getRequest()->getActionName();
    new Admin_Model_Resource_csvFileHeader( $actionName );
  

остальная часть кода здесь, чтобы получить данные для передачи в файл просмотра…

ресурс модели администратора выглядит следующим образом, поэтому он может использоваться любым контроллером acton…

 class Admin_Model_Resource_csvFileHeader
  

{

 private $_csvFileNameFromAction = null;

/**
 * Create the first part of the csv file name from the action name
 * @param <string> $actionName - name of the controller action for the report
 */
public function __construct( $actionName )
{
    $this->_csvFileNameFromAction = $actionName;
    $this->generateCsvHeader();
}

/**
 * Method is called direct from the constructor
 * to centralise and make consistent the csv file header
 * so it maximises code re-use
 * @return null - just generate the csv header
 */
public function generateCsvHeader()
{
    $dateSuffix = date('d-m-Y', time());
    $csvFileName = $this->_csvFileNameFromAction.'_'.$dateSuffix;

    header('Content-Type: text/x-csv; name="'.$csvFileName.'.csv"');
    header('Content-Disposition: inline; filename="'.$csvFileName.'.csv"');
    header('Pragma: public');
    header('Last-Modified: '.gmdate('D, d M Y H:i:s') . ' GMT');
    header('Cache-Control: no-store, no-cache, must-revalidate');
    header('Cache-Control: pre-check=0, post-check=0, max-age=0');
    header('Content-Transfer-Encoding: none');
}
  

}

Комментарии:

1. Я прочитал эту статью, она очень хорошая, любой вклад приветствуется. Я немного поработал над своим проектом из-за ограничений по времени, создав XML-файл, содержащий результаты запроса, а затем импортировал его в Excel.