Я пытаюсь использовать PHPWord для создания документа Word, который будет включать динамические данные, вытащенные из базы данных 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');
Есть ли способ исправить это?
Ну да. Но, к сожалению, вы должны изменить библиотеку. Автор библиотеки использует 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;
// ==== вот рабочий пример того, как данные слова могут записываться внутри шаблона слова // — загружать библиотеки 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
найти
$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- в функции section.php addText:
Я сделал это:
//$givenText = utf8_encode($text); $givenText = $text;
2- in cell.php функция addText
Я сделал это:
// $text = utf8_encode($text);
теперь ваш файл слова отобразит символы Unicode правильно. И тогда у меня была проблема в текстах. я нашел решение, используя этот код
$section->addText($val['notetitle'],array('textDirection'=>PHPWord_Style_Cell::TEXT_DIR_TBRL));
u может видеть две константы в файле cell.php
const TEXT_DIR_TBRL = 'tbRl'; const TEXT_DIR_BTLR = 'btLr';
обратите внимание, что u не может применять другие массивные комбинированные стили, такие как Paragraph, до «textDirection», потому что их стили отключили «textDirection».
Открыть PHPWord \ Template.php
Изменение функции setValue (строка № 89.), как показано ниже.
Измените $ replace = utf8_encode ($ replace); to $ replace = $ replace;