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.

    1. В setValue Функция (строка № 95) в Template.php, пожалуйста, прокомментируйте следующую часть кода

      //if(!is_array($replace)) {
      //    $replace = utf8_encode($replace);
      //}
      
    2. Если у вас есть проблема справа налево, которая на каком-то языке смешивает текст с текстом слева направо, добавьте следующий код в тот же 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.

Другие вопросы по тегам