Ошибка при создании файла Word с несколькими строками - PullRequest
0 голосов
/ 26 января 2019

Я пытаюсь выбрать данные из моей базы данных и показать данные в файле Word (DOCX).

Я работаю с данными двух типов.

Первый тип - данныечто я хочу показать один раз.Как и имя клиента.

Второй тип данных - это данные, которые импортируются с помощью сценария динамической строки.Данные в моей базе данных выглядят следующим образом: Строки:

-----------------------------------------
| internal_id | quantity | product_name |
|      1      |     1    |     One      |
|      1      |     5    |     Two      |
|      1      |     4    |    Three     |
|      1      |     2    |     Four     |
|      1      |     6    |     Five     |
-----------------------------------------

В моем шаблоне Word я определил эти строки следующим образом:

{name}
{address}
{lines}
{quantity}
{product_name}
{/lines}

Когда я выполняю свой скрипт, я получаю следующие данные вмой файл Word:

Name
Address 123
{!404_DOCXTemplate_quantity}
{!404_DOCXTemplate_product_name}

Кто-нибудь знает, почему многострочная часть моего кода не работает?

Вот мой PHP-скрипт, в котором я выбираю данные и генерирую файл Word:

$result1 = mysqli_fetch_assoc($res1) ;
$link2 = mysqli_connect("localhost", "root", "pass", "db");

if($link2 === false){
  die("ERROR: Could not connect. " . mysqli_connect_error());
}

$sql2 = "SELECT * FROM lines WHERE internal_id = '1'";
$res2 = mysqli_query($link2, $sql2) ;

$result2 = $link2->query($sql2);
if ($result2->num_rows > 0) {
$result2 = mysqli_fetch_assoc($res2) ;

  include_once('./docxtemplate.class.php');

  $docx = new DOCXTemplate('template.docx');

  $docx->set('name', "" . $result1['name'] . "");
  $docx->set('address', "" . $result1['address'] . "");

  $docx->set('LINES', mysqli_num_rows($result2));
  while ($row = mysql_fetch_array($result2))
    {
      $docx->set('quantity', "" . $result2['quantity'] . "");
      $docx->set('product_name', "" . $result2['product_name'] . "");
    }
  $docx->saveAs('test.docx');

  header("Content-Type:application/msword");
  header("Content-Disposition: attachment;filename=test.docx");

  readfile('test.docx');

}

Следующая функция генерирует текст !404_DOCXTemplate_ docxtemplate.class.php

private function _parse() {
    if ($doc = $this->getEntryData( 'word/document.xml' )) {
        if (preg_match_all('/\{[^}]+\}/', $doc, $m )) {
            foreach( $m[0] as $v ) {
                $var = preg_replace('/[\s\{\}]/','', strip_tags( $v ));
                if (isset( $this->data[ $var ] )) {
                    if (is_scalar( $this->data[ $var ] ))
                        $doc = str_replace( $v, $this->_esc( $this->data[ $var ] ), $doc );
                } else {
                    $doc = str_replace( $v, '{!404_'.__CLASS__.'_'.$var.'}', $doc );
                }
            }
        }
        $this->setEntryData( 'word/document.xml', $doc );
        return true;
    } else 
        return false;
}

Ответы [ 3 ]

0 голосов
/ 04 февраля 2019

В вашем коде довольно много ошибок для генерации данных, я добавил комментарии к коду, которые я считаю неправильными.

Вы смешиваете процедурные и объектные методы в вызовах mysqli_, это будет работать, но вы должны попытаться придерживаться одного или другого. Это помогает со стилем и удобочитаемостью. Методы объекта - это путь, по которому вы должны идти, но это также зависит от того, что уже используется.

Я не уверен, если вам нужно подключиться $link2, если у вас есть $link1, который является соединением с той же базой данных, затем повторно используйте это соединение. Попробуйте уменьшить количество подключений к базе данных, поскольку это обычно является большой проблемой производительности.

$sql2 = "SELECT quantity,product_name FROM lines WHERE internal_id = '1'";
// This is not needed - done twice next at- $result2 = $link2... 
// $res2 = mysqli_query($link2, $sql2) ;

$result2 = mysqli_query($link2, $sql2);
if (mysqli_num_rows($result2) > 0) {
    // This is done as part of the loop
    // $result2 = result2($res2) ;

    include_once('./docxtemplate.class.php');

    $docx = new DOCXTemplate('template.docx');

    // You don't need the "" . or ."" bits unless they add something
    $docx->set('name', $result1['name']);
    $docx->set('address', $result1['address']);

    $docx->set('LINES', mysqli_num_rows($result2));
    // use mysqli_fetch_assoc instead of mysql_fetch_array
    while ($row = mysqli_fetch_assoc($result2))
    {
        // $result2 should be $row
        $docx->set('quantity', $row['quantity']);
        $docx->set('product_name', $row['product_name']);
    }
    $docx->saveAs('test.docx');

    header("Content-Type:application/msword");
    header("Content-Disposition: attachment;filename=test.docx");

    readfile('test.docx');

}
0 голосов
/ 08 февраля 2019

Я думаю, что вы перезаписываете $ result2:

$result2 = $link2->query($sql2);
if ($result2->num_rows > 0) {
$result2 = mysqli_fetch_assoc($res2) ; // <- delete this line

, потому что позже вы делаете:

while ($row = mysql_fetch_array($result2))
0 голосов
/ 04 февраля 2019

Вы допустили ошибку опечатки здесь, в то время как цикл

while ($row = mysql_fetch_array($result2))
{
  $docx->set('quantity', "" . $row['quantity'] . "");
  $docx->set('product_name', "" . $row['product_name'] . "");
}

Вы используете $ result2 ['количество'] вместо $ row ['количество'] и $ result2 ['product_name'] вместо $ row[ 'product_name']

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...