Эта тема на forum.dklab.ru


Николай Булыгин: Перевод символов типа ✊ в нормальный вид
После парсинга XLS файла, если в файле встречаются русские символы, то они переводятся в спец. символы HTML, вот такой функцией:

function uc2html($str) {
$ret = '';
for( $i=0; $i<strlen($str)/2; $i++ ) {
$charcode = ord($str[$i*2])+256*ord($str[$i*2+1]);
$ret .= '&#'.$charcode;
}
return $ret;
}


Пробовал модифицировать данную функцию с помощью chr($charcode), но вылазиют кракозябли, такие же символы получаются при открытии файла по F3 в Norton(Total) Commander. Все было бы хорошо, если бы эти данные из файла не шли в базу, а сразу в HTML.
Дмитрий Котеров:
Кодировка какая? Если UTF-8, то переводить нужно совсем другой функцией:

function utf2entity($s) {
$tgt = '';
for($i=0,$len=strlen($s); $i<$len; $i++) {
$c = $s[$i];
$x = ord($c);
if ($x < 0x80) { // 1-байтовый символ
$tgt .= $c;
continue;
} elseif (($x & 0xC0) == 0xC0) { // (n+1)-байтовый символ
$n = 1;
while ( ($x & (0x40 >> $n)) > 0) $n++;
$code = $x & (0x3F >> $n);
for ($k=1; $k<=$n; $k++) {
$y = ord($s[$i+$k]) & 0x3F;
$code = ($code << 6) + $y;
}
$i += $n;
// В переменной $code содержится Unicode-код текущего символа.
// Здесь можно преобразовать его в нужную нам 8-битную кодировку или просто сделать из него HTML-entity.
$tgt .= '&#x'.dechex($code).';';
} else {
$tgt .= '?'; // такого не должно быть
}
}
return $tgt;
}

Николай Булыгин:
Дмитрий, как узнать какая кодировка у XLS файла? Я сделал по другому - не очень правильно я думаю:

function trash2rus($trashstr) {
$ru = array('Й', 'й',
'Ц', 'ц',
'У', 'у',
'К', 'к');
$trash = array('&#1049', '&#1081',
'&#1062', '&#1094',
'&#1059', '&#1091',
'&#1050', '&#1082');
return str_replace($trash, $ru, $trashstr);
}

Сейчас попробую ваш вариант.
Николай Булыгин:
O<AOG< - такие символы выводит эта функция. ;-(
Дмитрий Котеров:
Дмитрий, как узнать какая кодировка у XLS файла?
Что значит - "как узнать"? Там должно быть написано.
Кодировка самого XSLT-файла - в <?xml ... encoding="..."?>, если не ошибаюсь.
А кодировка результирующего документа, который получается после преобразований, в тэге <xslt:output> задается.
Николай Булыгин:
Дмитрий, Вы наверное неправильно меня поняли. Я говорю про файлы Microsoft Excel, не понимаю при чем тут XML? Причем это файлы не CSV, а именно XLS - файлы - т.е. как бы сказать - бинарные - что-ли. Внутри файла: РПаЎ±б >  юя     юяяя юяяя  яяяяяяяяяяя яяя яяяяяяяяяяя яяяяяяяяяяяяяя яяяяяяяяяяя яяяяяяяяяяя яяяяяяяя яяяяя яяяяяяяяя яяяяяяяяяяя яяяяяяяяяяяя   ќНБЂ  б  °Б  в \ p  IS
- такой ужас. При парсинге такого файла получаю что русские символы преобразуются в коды типа - &#3849 - но мне так не нужно. Хочу чтобы русские слова как были набраны в Excel-е, такими и выводились в HTML.
Дмитрий Котеров:
Ой. Это я XLS прочитал как XSLT, виноват. ;-)

При парсинге такого файла получаю что русские символы преобразуются в коды типа - &#3849
А чем парсите?

Вообще, уточните задачу. По крайней мере, опишите подробно, что имеется на входе, и что должно быть на выходе.
Николай Булыгин:
На входе имеется абсолютно любой файл в формате MS Excel, но не CSV - заказчик не хочет конвертировать. Данные из файла нужно заливать в базу, т.е. на выходе должны быть те же данные что и в файле. Парсингом занимается скрипт - который дал заказчик, это Zakkis.PHP.Excel.Parser.Pro.v4.0-SSG, http://www.zakkis.ca/products/abc_excelparser/index.php - но этот скрипт, выдает вместо простых букв - их коды, т.е. как вы назвали HTML entities, меня этот вариант не устраивает, т.к. некоторые строки мне еще нужно сравнивать, и вообще в базе к примеру сортировать, что неприемлимо - когда текст идет в виде &#23&#56&#32. Я справился с проблемой - писал уже выше - банальной заменой кода на его эквивалент. Функция получилась огромная, и думаю, что еще не все символы в ней учтены, хотя вбил туда все знаки которые только нашел на клавиатуре - думаю что это не правильно, и есть другой - более простой способ. Только какой? Подскажите где почитать про парсинг XLS файлов - только не CSV. К посту в качестве приложения даю скрипт парсинга, там в папке samlpes - есть пример xls2html - вот этот скрипт я и использую.
Николай Булыгин:
Прошу модераторов переименовать топик, т.к. он не соответствует названию, прошу вернуть старое название. Старое название: Перевод символов типа &#9994 в его эквивалент. Или же можно: Правильный парсинг ХЛС файлов.
Дмитрий Котеров:
Ну при чем тут XLS вообще, скажите на милость? В действительности, насколько я понял, задача ставится так. "Есть текст с вставленными HTML Entities вида &#XXXX;. Необходимо все entities преобразовать в символы кодировки windows-1251." Все верно?

Решение примерно такое:

function entities2windows($text)
{
return preg_replace_callback('/&#(\d+);/s', 'entities2windows_callback', $text)
}
function entities2windows_callback($p)
{
$c = $p[1];
if ($c < 256) return chr($c);
$u = pack('n', $c);
return @iconv('UCS-2BE', "windows-1251", $u);
}

При этом должно быть установлено расширение iconv, конечно (у большинства хостеров оно стоит).
Николай Булыгин:
Попытался запустить на своем личном компьютере, видать, у меня не установлено это расширение iconv, а смарти почему-то не выводит ошибку, ничего не отдает в браузер, хотя error_reporting(E-ALL). Где почитать про это расширение?
Дмитрий Котеров:
http://php.net/iconv
Если пользуетесь Денвером, скачайте пакет с библиотеками PHP. Если вручную ставили PHP - подключите расширение.
Николай Булыгин:
Дмитрий Котеров, спасибо за ценную информацию! Только в исходнике вы забыли ; поставить в функции entities2windows. Я ставил сам PHP пришлось кроме того, чтобы раскомментировать строчку в ini, скачать дополнительно библиотечку iconv.dll, только после этого заработало. Еще раз спасибо.
Dzeen:
Непонимаю, в чем дело.даже используя данную функцию, все равно не кодирует, и выводятся вышенаписанные кракозяблы....
Sawa:
Для правильной перекодировки в win-1251 нужно заменить строку
$s = uc2html($exc->sst['data'][$ind]);
на
$s = iconv("UTF-16LE", "Windows-1251", $exc->sst['data'][$ind]);
И конечно должен быть iconv установлен

Эта тема на forum.dklab.ru