PhpWord 输出在 LibreOffice 中不起作用,但在 MS Word 中工作正常

如何解决PhpWord 输出在 LibreOffice 中不起作用,但在 MS Word 中工作正常

这与 GitHub 页面 [link] 上列出的一个半已知问题有关,其中 PhpWord 生成表格的方式导致它将单元格宽度设置为“”,这在 LibreOffice 中无效,但是在 Word 中没问题。

GitHub 上的问题专门列出了 html-to-word 转换,但我在使用常规的面向对象界面时也遇到了这个问题。

我尝试手动设置单元格宽度,但似乎没有任何作用。

我在这里询问是否有人对此问题有任何解决方法,因为它几乎不可能在不访问 MS Word 的情况下在 Linux 机器上调试我的输出。我需要为客户导出 .docx。

为什么不直接导出到 .odt 来测试呢?如果我这样做,它也不会呈现我在页面上的列表......

这是我正在处理的文档的粗略大纲(由于保密协议,我不能随意分享确切的代码):

$document = new PhpWord\PhpWord();
$section = $document->addSection();

// This list doesn't get rendered in the ODT file
$section->addListItem('Employee ID: 98765');
$section->addListItem('First Name: John');
$section->addListItem('Last Name: Doe');
$section->addListItem('SSN: 12345');

// This table has errors in LibreOffice when exported to .docx
if ($show_adv_details) {
    $table = $section->addTable();
    $table->addRow();
    $table->addCell()->addText('SSN');
    $table->addCell()->addText('Email');
    $table->addCell()->addText('Phone No');
    
    $table->addRow();
    $table->addCell()->addText('12345');
    $table->addCell()->addText('jd@example.com');
    $table->addCell()->addText('999 1234');

    // repeat ad nauseam
}

$section->addTitle('Comment');
$section->addTitle('Lorem ipsum dolor sit amet,consectetur adipiscing elit,sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.');

我在 Ubuntu 上使用 PHP 7.0(古老的遗留系统,对此无能为力)。

所以在最后重申一下这个问题:

我可以做些什么来使该文档在所有不同的输出上正确呈现?文档似乎没有多大帮助。

解决方法

好吧,我不是 PHPOffice 包的维护者,但这里有一个解决方法,我挖掘了包代码并解决了您的两个问题:

  1. ODT 列表不起作用;
  2. 使用 LibreOffice 打开 Word2007 Writer 上的表格不起作用。

我意识到 ODText 编写器上不存在 ListItem.php 类,我想这是因为您无法将列表添加到 .odt 文件中。

您需要手动为列添加宽度以使其在 LibreOffice 上工作(如 Nigel 所说,您可以通过每个 addCell() 调用并添加一些数字,甚至“1”也可以)。

如何解决这两个问题

我们将“覆盖”原始文件,并提供一些解决问题的更新。 为了使其工作,您应该使用 Composer 安装 PHPWord(这是安装指南中唯一可用的选项,但还有其他方法可以做到这一点)。

如果没有 Composer,PHPWord require 之后需要自定义文件(我认为它有效)。或者直接更改其位置上的文件(一个坏主意)。

文件

创建一个这样的结构:

Custom
├── Element
│   └── Table.php
└── Writer
    └── ODText
        └── Element
            └── ListItem.php

当然,您可以使用任何其他文件,但我们将“覆盖”包的原始文件,因此我保留了其结构。

我们将使用 Autoload Files 来获取这些文件:

composer.json

...
"autoload": {
    "files": [
        "Custom/Element/Table.php","Custom/Writer/ODText/Element/ListItem.php"
    ]
},...

如果您的 composer.json 上没有“自动加载”键,您必须添加它,“文件”键也是如此。

运行 composer dump-autoload 以更新更改。

自定义类

现在,我们必须将代码添加到我们的自定义文件中。

Custom/Writer/ODText/Element/ListItem.php

<?php
namespace PhpOffice\PhpWord\Writer\ODText\Element;

/**
 * ListItem element writer
 */
class ListItem extends AbstractElement
{
    /**
     * Write list item element.
     */
    public function write()
    {
        $xmlWriter = $this->getXmlWriter();
        $element = $this->getElement();
        if (!$element instanceof \PhpOffice\PhpWord\Element\ListItem) {
            return;
        }
        
        $textObject = $element->getTextObject();

        $xmlWriter->startElement('text:list');
        $xmlWriter->writeAttribute('text:style-name','L1');

        $xmlWriter->startElement('text:list-item');

        $xmlWriter->startElement('text:p');
        $xmlWriter->writeAttribute('text:style-name','P1');

        $elementWriter = new Text($xmlWriter,$textObject,true);
        $elementWriter->write();

        $xmlWriter->endElement(); // text:list
        $xmlWriter->endElement(); // text:p
        $xmlWriter->endElement(); // text:list-item
    }
}

该文件已改编自 Word2007 版本并修复了您的第一个问题。现在列表将适用于 ODText。

自定义/元素/Table.php

<?php
namespace PhpOffice\PhpWord\Element;

use PhpOffice\PhpWord\Style\Table as TableStyle;

/**
 * Table element writer
 */
class Table extends AbstractElement
{
    /**
     * Table style
     *
     * @var \PhpOffice\PhpWord\Style\Table
     */
    private $style;

    /**
     * Table rows
     *
     * @var \PhpOffice\PhpWord\Element\Row[]
     */
    private $rows = array();

    /**
     * Table width
     *
     * @var int
     */
    private $width = null;

    /**
     * Create a new table
     *
     * @param mixed $style
     */
    public function __construct($style = null)
    {
        $this->style = $this->setNewStyle(new TableStyle(),$style);
    }

    /**
     * Add a row
     *
     * @param int $height
     * @param mixed $style
     * @return \PhpOffice\PhpWord\Element\Row
     */
    public function addRow($height = null,$style = null)
    {
        $row = new Row($height,$style);
        $row->setParentContainer($this);
        $this->rows[] = $row;

        return $row;
    }

    /**
     * Add a cell
     *
     * @param int $width
     * @param mixed $style
     * @return \PhpOffice\PhpWord\Element\Cell
     */
    public function addCell($width = 1,$style = null)
    {
        $index = count($this->rows) - 1;
        $row = $this->rows[$index];
        $cell = $row->addCell($width,$style);

        return $cell;
    }

    /**
     * Get all rows
     *
     * @return \PhpOffice\PhpWord\Element\Row[]
     */
    public function getRows()
    {
        return $this->rows;
    }

    /**
     * Get table style
     *
     * @return \PhpOffice\PhpWord\Style\Table
     */
    public function getStyle()
    {
        return $this->style;
    }

    /**
     * Get table width
     *
     * @return int
     */
    public function getWidth()
    {
        return $this->width;
    }

    /**
     * Set table width.
     *
     * @param int $width
     */
    public function setWidth($width)
    {
        $this->width = $width;
    }

    /**
     * Get column count
     *
     * @return int
     */
    public function countColumns()
    {
        $columnCount = 0;

        $rowCount = count($this->rows);
        for ($i = 0; $i < $rowCount; $i++) {
            /** @var \PhpOffice\PhpWord\Element\Row $row Type hint */
            $row = $this->rows[$i];
            $cellCount = count($row->getCells());
            if ($columnCount < $cellCount) {
                $columnCount = $cellCount;
            }
        }

        return $columnCount;
    }

    /**
     * The first declared cell width for each column
     *
     * @return int[]
     */
    public function findFirstDefinedCellWidths()
    {
        $cellWidths = array();

        foreach ($this->rows as $row) {
            $cells = $row->getCells();
            if (count($cells) <= count($cellWidths)) {
                continue;
            }
            $cellWidths = array();
            foreach ($cells as $cell) {
                $cellWidths[] = $cell->getWidth();
            }
        }

        return $cellWidths;
    }
}

当我们“覆盖”文件时,我们不能重用扩展它的原始文件(至少我不知道如何)。此处唯一的更改是 public function addCell($width = 1,$style = null) 始终将“1”作为函数的默认值。这解决了您的第二个问题,现在您可以在没有值的情况下调用 $table->addCell()

演示

require __DIR__ . '/vendor/autoload.php';

$document = new \PhpOffice\PhpWord\PhpWord();

$section = $document->addSection();

// This list **does** get rendered in the ODT file
$section->addListItem('Employee ID: 98765');
$section->addListItem('First Name: John');
$section->addListItem('Last Name: Doe');
$section->addListItem('SSN: 12345');

$table = $section->addTable();
$table->addRow();
$table->addCell()->addText('SSN');
$table->addCell()->addText('Email');
$table->addCell()->addText('Phone No');

$table->addRow();
$table->addCell()->addText('12345');
$table->addCell()->addText('jd@example.com');
$table->addCell()->addText('999 1234');

// Save the document as DOCX
$objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($document,'Word2007');
$objWriter->save('document.docx');

// Save the document as ODT
$objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($document,'ODText');
$objWriter->save('document.odt');

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res