utf 8 — Запись строк UTF-8 в Word с использованием PHP / COM

Я пытаюсь сгенерировать документ Word, используя данные из базы данных MySQL, используя PHP / COM. Если данные из базы данных представляют собой простой текст ASCII (например, «привет»), они правильно отображаются в документе Word. Если данные содержат не ASCII (многобайтовой) (например, «маори»), они отображаются правильно, но в конце имеют «забавные» символы (например, NULL, пробелы или китайские символы).

СредаЯ использую Windows 7 Enterprise, Apache, MySQL, PHP 5.2.17 и Microsoft Office 2010.

Вот упрощенный пример — я даже не использую базу данных и не пишу в документ Word, а просто использую Word CleanString Способ воспроизведения проблемы:

private function _cleanString($wordApp, $str)
{
$vStr = new VARIANT($str, VT_BSTR, CP_UTF8);
$bytes = strlen($vStr);
$chars = mb_strlen($vStr, "UTF-8");
echo "Test string: $vStr (bytes=$bytes, chars=$chars)<br/>";
$vStr = $wordApp->CleanString($vStr);
$bytes = strlen($vStr);
$chars = mb_strlen($vStr, "UTF-8");
echo "Test string (after cleaning): $vStr (bytes=$bytes, chars=$chars)<br/>";
echo "<br/>";
}

public function testUtf8Strings()
{
com_load_typelib('Word.Application');
// Specifying codepage as CP_UTF8 to let COM/Word know strings I pass in will be in UTF-8 format.
$wordApp = new COM("word.application", null, CP_UTF8) or die ("couldn't create an instance of word");
echo "Loaded Word, version {$wordApp->Version} <br/>";
$wordApp->visible = false;

echo "<br/>";
$this->_cleanString($wordApp, 'No multi-byte characters.');
$this->_cleanString($wordApp, 'Multi-byte chars: Māori 楠 test.');
$this->_cleanString($wordApp, 'Multi-byte chars: Ā ā Ē ē Ī.');

$wordApp->Quit(false); // Imortant: must say 'false', otherwise Word does not close
$wordApp = null;
echo "Quit Word.";

return;
}

HTML-вывод:

Loaded Word, version 14.0

Test string: No multi-byte characters. (bytes=25, chars=25)
Test string (after cleaning): No multi-byte characters. (bytes=25, chars=25)

Test string: Multi-byte chars: Māori 楠 test. (bytes=34, chars=31)
Test string (after cleaning): Multi-byte chars: Māori 楠 test. 5⹮ (bytes=39, chars=34)

Test string: Multi-byte chars: Ā ā Ē ē Ī. (bytes=33, chars=28)
Test string (after cleaning): Multi-byte chars: Ā ā Ē ē Ī. 琠獥⹴㔠 (bytes=46, chars=33)

Quit Word.

CleanString Метод удаляет непечатаемые символы из заданной строки и заменяет их пробелами. Поскольку мои строки уже «чистые», я ожидаю получить ту же строку обратно. Это не тот случай, когда моя строка содержит многобайтовые символы. Похоже, Word использует количество байтов из исходной строки, чтобы быть количеством символов в возвращаемой строке.

3

Решение

Оказывается, это была ошибка PHP (https://bugs.php.net/bug.php?id=66431) исправлено в PHP 5.4.29. Я тестировал с PHP 5.5.19, и проблема больше не возникает. HTML-вывод:

Loaded Word, version 14.0

Test string: No multi-byte characters. (bytes=25, chars=25)
Test string (after cleaning): No multi-byte characters. (bytes=25, chars=25)

Test string: Multi-byte chars: Māori 楠 test. (bytes=34, chars=31)
Test string (after cleaning): Multi-byte chars: Māori 楠 test. (bytes=34, chars=31)

Test string: Multi-byte chars: Ā ā Ē ē Ī. (bytes=33, chars=28)
Test string (after cleaning): Multi-byte chars: Ā ā Ē ē Ī. (bytes=33, chars=28)

Quit Word.
0

Другие решения

Других решений пока нет …