Чтение Excel-файлов средствами PHP

Если вам необходимо читать файлы Excel (.xls) средствами PHP, то библиотека PHP-ExcelReader создана специально для вас. Для работы необходима поддержка iconv или mbstring. Вот пример того, как можно оформить вывод xls-документа в HTML-таблицу с использованием этой библиотеки:

<?php
require_once ('Excel/reader.php');

$data = new Spreadsheet_Excel_Reader();
$data->setOutputEncoding('CP1251');
$data->read('filename.xls');     

echo '<table>';
for ($i = 1; $i <= $data->sheets[0]['numRows']; $i++) {
  echo '<tr>';
  for ($j = 1; $j <= $data->sheets[0]['numCols']; $j++) {
    echo '<td>'.$data->sheets[0]['cells'][$i][$j].'</td>';
  }
  echo '</tr>';
}
echo '</table>';
?>

Альтернативный вариант - PHP Excel PARSER. Вот что написано в файле Help_rus.txt:

Вам нужен скрипт, который может читать MS файлы Excel и сохранять данные в базе данных, HTML страницах и и т.д.? Вы хотите делать это используя PHP под Unix и Linux, но без того, чтобы использовать инструментальные средства Windows напоподобии COM? Тогда PHP Excel PARSER - для вас. Все, в чем вы будете нуждаться - это только наш excel.php и PHP сервер без установки дополнительных инструментальных средств.

В файле документации Help_rus.txt довольно подробно описано, как использовать PHP Excel PARSER. Кроме того, дистрибутив содержит примеры работы с Excel-файлом:

  • PHP Excel Parser/Setup/SAMPLE/XLS2HTML/SAMPLE.PHP - вывод Excel-файла в браузер
  • PHP Excel Parser/Setup/SAMPLE/xls2mysql/INDEX.PHP - запись Excel-файла в базу данных

Пример вывода Excel-файла в браузер в формате HTML:

<?php
include ("excel.php");

$exc = new ExcelFileParser ("log.txt", ABC_NO_LOG);
$res = $exc->ParseFromFile("test.xls");

switch ($res) {
    case 0: break;
    case 1: die ("Невозможно открыть файл");
    case 2: die ("Файл, слишком маленький чтобы быть файлом Excel");
    case 3: die ("Ошибка чтения заголовка файла");
    case 4: die ("Ошибка чтения файла");
    case 5: die ("Это - не файл Excel или файл, сохраненный в Excel < 5.0");
    case 6: die ("Битый файл");
    case 7: die ("В файле не найдены данные  Excel");
    case 8: die ("Неподдерживаемая версия файла");
    default: die ("Неизвестная ошибка");
}

// цикл по рабочим листам
for( $ws_num=0; $ws_num<count($exc->worksheet['name']); $ws_num++ )
{                 
    echo "<h3>Рабочий лист: ";
    if( $exc->worksheet['unicode'][$ws_num] )
        echo uc2cp1251($exc->worksheet['name'][$ws_num]);
    else
        echo $exc->worksheet['name'][$ws_num];

    echo "</h3>\n";
    $ws = $exc->worksheet['data'][$ws_num];

    // если рабочий лист не пустой
    if ( is_array($ws) && isset($ws['max_row']) && isset($ws['max_col']) ) {
        echo "<table border=1 cellspacing=0 cellpadding=2>\n";

        echo "<tr><td>&nbsp;</td>";
        for( $j=0; $j<=$ws['max_col']; $j++ ) {
            echo "<td class=index>&nbsp;";
            if( $j>25 ) echo chr((int)($j/26)+64);
            echo chr(($j % 26) + 65)."&nbsp;</td>";
        }
        echo "</tr>\n";
        // начало цикла по строкам
        for( $i=0; $i<=$ws['max_row']; $i++ ) {
            echo "<tr><td class=index>".($i+1)."</td>\n";
            // начало цикла по столбцам
            if( isset($ws['cell'][$i]) && is_array($ws['cell'][$i]) ) {
                for( $j=0; $j<=$ws['max_col']; $j++ )
                {
                    if( isset($ws['cell'][$i][$j]) ) {

                        // Печать данных ячейки
                        echo "<td>";
                        $data = $ws['cell'][$i][$j];
                       
                        switch ($data['type'])
                        {
                            // строка
                            case 0:
                                $ind = $data['data'];
                                if( $exc->sst['unicode'][$ind] )
                                    $s = uc2cp1251($exc->sst['data'][$ind]);
                                else
                                    $s = $exc->sst['data'][$ind];
                                if( strlen(trim($s))==0 )
                                    echo "&nbsp;";
                                else
                                    echo $s;
                                break;
                            //целое число
                            case 1:
                                echo (int)($data['data']);
                                break;
                            //вещественное число
                            case 2:
                                echo (float)($data['data']);
                                break;
                            // дата
                            case 3:
                                $ret = $exc->getDateArray($data['data']);
                                printf ("%s-%s-%s",$ret['day'], $ret['month'], $ret['year']);
                                break;
                            default:
                                echo "&nbsp;";
                                break;
                        }
                        echo "</td>\n";
                           
                    } else {
                        echo "<td>&nbsp;</td>\n";
                    }
                }
            } else {
                // все ячейки стрки пустые
                for( $j=0; $j<=$ws['max_col']; $j++ ) {
                    echo "<td>&nbsp;</td>\n";
                }
            }
            echo "</tr>\n";
           
        }

        echo "</table>\n";
    } else {
        // пустой рабочий лист
        echo "<p>Пустой рабочий лист</p>\n";
    }
} 

// конвертим в нужную кодировку
function uc2cp1251($str) {
    return iconv('UNICODELITTLE','cp1251',$str);
}
?>

Ссылки по теме:

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

  1. Mikhail:

    а как в полевых испытаниях с кириллицей в экселевских файлах, всё нормально?

    я одно время просто искал решение и в итоге пришел к тому, что (по крайней мере на момент написания скриптов для конкретной задачи) более стабильно в отношении кириллицы написалось на Perl с использованием SpreadSheet::ParseExcel.

  2. admin:

    Mikhail, я пробовал в работе оба скрипта - с кириллицей все нормально. Для PHP-ExcelReader кодировка устанавливается так
    $data->setOutputEncoding(’CP1251′);
    а для PHP Excel PARSER перекодировать данные для каждой ячейки
    iconv(’UNICODELITTLE’, ‘cp1251′, $str);

  3. Onwave:

    Как установить PHP Excel PARSER?

  4. orko:

    echo “tr td   /td \n”;
    for( $j=0; $j<=$ws['max_col']; $j++ ) {
    echo “ ”;
    if( $j>25 ) echo chr((int)($j/26)+64);
    echo chr(($j % 26) + 65).” ”;
    }

    tr после цикла не закрыт.

  5. admin:

    orko, спасибо, исправил.

  6. Dmitry Alexandrovich:

    http://www.conone.ru - конвертор справочников 1С Предприятие 7.7 или таблицы Excel в PHP далее в таблицу MySQL.
    Удачи!

  7. Simon:

    Возможно ли как-то обработать файл excel сохраненный в виде html-страницы таким же способом как это делает Spreadsheet_Excel_Reader?
    Проблема в том, что Spreadsheet_Excel_Reader не понимает excel файл сохраненный в виде html-страницы.
    Парсить html код в моей задачи не приемлемо.

  8. admin:

    Парсить html код в моей задачи не приемлемо
    Я другого выхода не вижу - PCRE в помощь.

  9. Петр:

    Отличная библиотека, хорошо работает и понимает кириллицу.
    для нее нужна библиотеки iconv (если PHP<5) и mb_string

  10. SPro:

    Спасибо создателю.
    Всё отлично работает.
    Дай Бог тебе здоровья добрый человек!!!

  11. Костя:

    функция перекодировки не верна!

    ВЕРО:

    // конвертим в нужную кодировку
    function uc2cp1251($str) {
    return iconv(’UTF-8′,’windows-1251′,$str);
    }

    у меня так - работает!

  12. Александра:

    Спасибо огромное. то что нужно было!

  13. Levik:

    При работе с phpexcelreader иногда бывают проблемы с датой (+- один день).

  14. Peter:

    Парсер работает на ура!!!
    Вот только как быть с .xlsx форматом?! Очень нужно, чтобы любой читал!!!

  15. PaLinkaPro:

    Спасибо, то что надо - все работает отлично!!!!

  16. Константин:

    Спасибо за наводку!

Оставьте свой отзыв