PHPWord: создание арабского документа справа налево
Я пытаюсь использовать PHPWord для создания текстового документа, который будет включать динамические данные, извлеченные из базы данных MySQL. База данных имеет кодировку MySQL: UTF-8 Unicode
(utf8) Параметры сортировки MySQL: utf8_unicode_ci
и поля таблицы тоже.
Данные хорошо сохраняются и предварительно просматриваются в HTML, однако при создании документа с арабскими переменными вывод в Word выглядит следующим образом Ø£ØÙد Ùبار٠اÙÙرÙ
,
$PHPWord = new PHPWord();
$document = $PHPWord->loadTemplate('templates/.../wtvr.docx');
$document->setValue('name', $name);
$document->setValue('overall_percent_100', $overall_percent_100);
$document->save('Individual Report - ' . $name . '.docx');
Есть ли способ исправить это?
5 ответов
Ну да. Но вы, к сожалению, должны изменить библиотеку. Автор библиотеки использует utf8_encode/utf8_decode
очевидно, не понимая, что они делают вообще.
На линии 150, из Shared/String.php
:
замещать
public static function IsUTF8($value = '') {
return utf8_encode(utf8_decode($value)) === $value;
}
С
public static function IsUTF8($value = '') {
return mb_check_encoding($value, "UTF-8");
}
Тогда, если вы делаете
$ grep -rn "utf8_encode" .
В корне проекта вы найдете все строки, где utf8_encode
используется. Вы увидите строки, как
$linkSrc = utf8_encode($linkSrc); //$linkSrc = $linkSrc;
$givenText = utf8_encode($text); //$givenText = $text;
Вы можете просто удалить utf8_encode
как показано в комментариях.
Почему utf8_encode/utf8_decode
неправильно? Прежде всего, потому что это не то, что они делают. Они делают from_iso88591_to_utf8
а также from_utf8_to_iso88591
, Во-вторых, ISO-8859-1 почти никогда не используется, и обычно, когда кто-то заявляет, что использует его, он фактически использует Windows-1252. ISO-8859-1 - это очень маленький набор символов, даже не способный к кодированию €
не говоря уже о арабских письмах.
Вы можете быстро просмотреть библиотеку, выполнив:
$ grep -rn "utf8_\(en\|de\)code" .
Если вы получаете совпадения, вы должны идти дальше и искать другую библиотеку. Эти функции просто делают неправильно каждый раз, и даже если кому-то нужен какой-то крайний случай для использования этих функций, гораздо лучше быть откровенным об этом, когда вам действительно нужен ISO-8859-1, потому что обычно вы этого никогда не делаете.
Пожалуйста, найдите следующие пункты, чтобы написать все типы вставки данных utf-8 справа налево в шаблон phpword.
В
setValue
Функция (строка № 95) в Template.php, пожалуйста, прокомментируйте следующую часть кода//if(!is_array($replace)) { // $replace = utf8_encode($replace); //}
Если у вас есть проблема справа налево, которая на каком-то языке смешивает текст с текстом слева направо, добавьте следующий код в тот же
setValue
функция.$replace = "<w:rPr><w:rtl/></w:rPr>".$replace;
// ==== вот рабочий пример того, как слово data может быть записано внутри шаблона слова // --- загрузить библиотеки phpword ----
$this->load->library("phpword/PHPWord");
$PHPWord = new PHPWord();
$document = $PHPWord->loadTemplate('./forms/data.docx');
$document->setValue('NAME', 'شراف الدين');
$document->setValue('SURNAME', 'مشرف');
$document->setValue('FNAME', 'ظهرالدين');
$document->setValue('MYVALUE', '15 / سنبله / 1363');
$document->setValue('PROVINCE', 'سمنگان');
$document->setValue('DNAME', 'عبدالله');
$document->setValue('DMOBILE', '0775060701');
$document->setValue('BOX','<w:sym w:font="Wingdings" w:char="F06F"/>');
$document->setValue('NO','<w:sym w:font="Wingdings" w:char="F06F"/>');
//$document->setValue('BOX2','<w:sectPr w:rsidR="00000000"><w:pgSz w:w="12240" w:h="15840"/><w:pgMar w:top="1440" w:right="1440" w:bottom="1440" w:left="1440" w:header="720" w:footer="720" w:gutter="0"/><w:cols w:space="720"/><w:docGrid w:linePitch="360"/>');
$document->setValue('YES','<w:sym w:font="Wingdings" w:char="F0FE"/>');
$document->setValue('CLASS1','<w:sym w:font="Wingdings" w:char="F06F"/>');
$document->setValue('CLASS2','<w:sym w:font="Wingdings" w:char="F0FE"/>');
$document->setValue('DNAME','يما شاه رخي');
$document->setValue('TEL','0799852369');
$document->setValue('ENTITY','مشاور حقوقي و نهادي');
$document->setValue('ENTITY','مشاور حقوقي و نهادي');
$document->setValue('REMARKS','در مسابقات سال 2012 میلادی در میدان Judo بر علاوه به تعداد 39 نفر در تاریخ 4/میزان/ سال 1391 قرار ذیل اند.');
$file = "./forms/data2.docx";
$document->save($file);
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=data2.docx");
header("Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document");
header("Content-Transfer-Encoding: binary");
ob_clean();
flush();
readfile($file);
// нужно, как дизайн может изменить внешний вид.
colr #E4EDF9
Откройте PHPWord\Template.php
Измените функцию setValue (строка № 89), как показано ниже.
Изменить $replace = utf8_encode($replace); $replace = $replace;
Найти
$objWriter->startElement('w:t');
$objWriter->writeAttribute('xml:space', 'preserve'); // needed because of drawing spaces before and after text
$objWriter->writeRaw($strText);
$objWriter->endElement();
В Writer/Word2007/Base.php
заменить
$objWriter->startElement('w:textDirection');
$objWriter->writeAttribute('w:val', 'rlTb');
$objWriter->startElement('w:t');
$objWriter->writeAttribute('xml:space', 'preserve'); // needed because of drawing spaces before and after text
$objWriter->writeRaw($strText);
$objWriter->endElement();
$objWriter->endElement();
Кроме того, убедитесь, что вы не используете какие-либо стили, чтобы заставить его работать, иначе вам придется повторять этот шаг в каждой функции, которую вы используете.
Я должен был исправить это в двух местах, отличных от способа Насера:
1- в функции addText для Section.php:
Я сделал это:
//$givenText = utf8_encode($text);
$givenText = $text;
2- в функции addText в cell.php
Я сделал это:
// $text = utf8_encode($text);
Теперь ваш файл слова будет отображать символы Юникода в правильном направлении. А потом у меня возникла проблема с текстовыми указаниями. я нашел решение с помощью этого кода
$section->addText($val['notetitle'],array('textDirection'=>PHPWord_Style_Cell::TEXT_DIR_TBRL));
вы можете увидеть две константы в файле cell.php
const TEXT_DIR_TBRL = 'tbRl';
const TEXT_DIR_BTLR = 'btLr';
обратите внимание, что вы не можете применять другие комбинированные стили массива, такие как Paragraph, прежде чем textDirection, потому что из-за стилей отключено textDirection.