PHPWord生成多篇word文档的时候目录文件冗余bug解决方案

phpword的开源链接在这里:https://github.com/PHPOffice/PHPWord,PHPword是很多服务端技术为php的网站上的word下载的功能支撑技术。

其原理并不难以理解,因为word可以解析xml形式的数据,所以phpword本质是生成一个xml文件。

相关介绍可以参考:https://support.office.com/zh-cn/article/Open-XML-%E6%A0%BC%E5%BC%8F%E5%92%8C%E6%96%87%E4%BB%B6%E6%89%A9%E5%B1%95%E5%90%8D-5200d93c-3449-4380-8e11-31ef14555b18

在phpword中,生成目录只能依靠建立标题,然后对标题进行索引生成可触发链接的目录。所以你只需要调用addTitle函数即可生成目录,网上中文文档中说的addTOC函数本身不会生成目录,其只是修改的目录的格式,例如字号、字体、颜色之类。

以上逻辑在生成单篇word文档时没有任何问题,但是如果你想生成多篇word文档,每篇文档的目录只是当前word的目录,就会发现很严重的目录冗余。经过分析可以看出其冗余内容为把前面生成的word的目录补充。开发人员的思维这里一定想到一个关键字:static。

没错。

在其PHPWord_TOC类中,所有的变量都是static。刚才去github看了下这个bug可能已经修改,我使用的文件是这个:

  1 <?php
  2 /**
  3  * PHPWord
  4  *
  5  * Copyright (c) 2011 PHPWord
  6  *
  7  * This library is free software; you can redistribute it and/or
  8  * modify it under the terms of the GNU Lesser General Public
  9  * License as published by the Free Software Foundation; either
 10  * version 2.1 of the License, or (at your option) any later version.
 11  *
 12  * This library is distributed in the hope that it will be useful,
 13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 15  * Lesser General Public License for more details.
 16  *
 17  * You should have received a copy of the GNU Lesser General Public
 18  * License along with this library; if not, write to the Free Software
 19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 20  *
 21  * @category   PHPWord
 22  * @package    PHPWord
 23  * @copyright  Copyright (c) 010 PHPWord
 24  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
 25  * @version    Beta 0.6.3, 08.07.2011
 26  */
 27
 28
 29 /**
 30  * PHPWord_TOC
 31  *
 32  * @category   PHPWord
 33  * @package    PHPWord_TOC
 34  * @copyright  Copyright (c) 2011 PHPWord
 35  */
 36 class PHPWord_TOC {
 37
 38     /**
 39      * Title Elements
 40      *
 41      * @var array
 42      */
 43     private static $_titles = array();
 44
 45     /**
 46      * TOC Style
 47      *
 48      * @var array
 49      */
 50     private static $_styleTOC;
 51
 52     /**
 53      * Font Style
 54      *
 55      * @var array
 56      */
 57     private static $_styleFont;
 58
 59     /**
 60      * Title Anchor
 61      *
 62      * @var array
 63      */
 64     private static $_anchor = 252634154;
 65
 66     /**
 67      * Title Bookmark
 68      *
 69      * @var array
 70      */
 71     private static $_bookmarkId = 0;
 72
 73
 74     /**
 75      * Create a new Table-of-Contents Element
 76      *
 77      * @param array $styleFont
 78      * @param array $styleTOC
 79      */
 80     public function __construct($styleFont = null, $styleTOC = null) {
 81         self::$_styleTOC = new PHPWord_Style_TOC();
 82         self::$_bookmarkId=0;
 83         self::$_anchor=252634154;
 84         self::$_titles=array();
 85         if(!is_null($styleTOC) && is_array($styleTOC)) {
 86             foreach($styleTOC as $key => $value) {
 87                 if(substr($key, 0, 1) != ‘_‘) {
 88                     $key = ‘_‘.$key;
 89                 }
 90                 self::$_styleTOC->setStyleValue($key, $value);
 91             }
 92         }
 93
 94         if(!is_null($styleFont)) {
 95             if(is_array($styleFont)) {
 96                 self::$_styleFont = new PHPWord_Style_Font();
 97
 98                 foreach($styleFont as $key => $value) {
 99                     if(substr($key, 0, 1) != ‘_‘) {
100                         $key = ‘_‘.$key;
101                     }
102                     self::$_styleFont->setStyleValue($key, $value);
103                 }
104             } else {
105                 self::$_styleFont = $styleFont;
106             }
107         }
108     }
109
110     /**
111     * Add a Title
112     *
113     * @return array
114     */
115     public static function addTitle($text, $depth = 0) {
116         $anchor = ‘_Toc‘.++self::$_anchor;
117         $bookmarkId = self::$_bookmarkId++;
118
119         $title = array();
120         $title[‘text‘] = $text;
121         $title[‘depth‘] = $depth;
122         $title[‘anchor‘] = $anchor;
123         $title[‘bookmarkId‘] = $bookmarkId;
124
125         self::$_titles[] = $title;
126
127         return array($anchor, $bookmarkId);
128     }
129
130     /**
131      * Get all titles
132      *
133      * @return array
134      */
135     public static function getTitles() {
136         return self::$_titles;
137     }
138
139     /**
140      * Get TOC Style
141      *
142      * @return PHPWord_Style_TOC
143      */
144     public static function getStyleTOC() {
145         return self::$_styleTOC;
146     }
147
148     /**
149      * Get Font Style
150      *
151      * @return PHPWord_Style_Font
152      */
153     public static function getStyleFont() {
154         return self::$_styleFont;
155     }
156 }
157 ?>

解决这个bug,我的方法是增加了82、83、84行,把所有的数据都重新初始化,这样就不会有问题了。

时间: 2024-10-12 14:42:22

PHPWord生成多篇word文档的时候目录文件冗余bug解决方案的相关文章

自动生成并导出word文档

今天很荣幸又破解一现实难题:自动生成并导出word文档 先看页面效果: word效果: 代码: 先搭建struts2项目 创建action,并在struts.xml完成注册 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"

php学习笔记之将word文档转化为HTML文件

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-

C# WebForm 使用NPOI 2 生成简单的word文档(.docx)

使用NPOI可以方便的实现服务端对Word.Excel的读写.要实现对Word的读写操作,需要引用NPOI.OOXML.dll,应用命名空间XWPF. 本文使用NPOI 2.0实现对Word的基本生成.下载操作. NOPI 2.0 下载地址:http://npoi.codeplex.com/downloads/get/764162 虽然现在最新版本为NPOI 2.1.1 ,但笔者使用2.1.1的NPOI.OOXML.dll时,发现无法实现段落格式化功能,故推荐使用本文版本. 需要添加的命名空间:

Java中用Apache POI生成excel和word文档

概述: 最近在做项目的过程中遇到了excel的数据导出和word的图文表报告的导出功能,最后决定用Apache POI来完成该项功能.本文就项目实现过程中的一些思路与代码与大家共享,同时,也作为自己的一个总结,以备后用. 功能: 1.从数据库查询数据导出为excel: 2.导出word的包括,内容有文字,图片,表格等. 效果: 导出excel 导出word 实现代码: 1.导出excel package beans.excel; import java.io.FileOutputStream;

根据Excel的内容和word模板生成对应的word文档

Sub setname() Dim I As Integer Dim pspname As String Dim pspnumber As String Dim path As String Dim srcPath As String Dim srcPath2 As String Dim wordApp As Object Dim wordDoc As Object Dim wordArange As Object Dim wordSelection As Object Dim ReplaceS

判断pdf、word文档、图片等文件类型(格式)、大小的简便方法

很久没发文了,今天有时间就写一下吧. 关于上传文件,通常我们都需要对其进行判断,限制上传的类型,如果是上传图片,我们甚至会把图片转化成base64数据后,再进行上传.普遍的方法是直接写在上传按钮的触发方法里面,但是对于大型的项目而言,这必然是会重复着同一段代码,使得代码臃肿繁重,这样也不利于平台的优化以及后续的维护,于是,我便封装了一个小小的判断上传文件的类型,图片类型的简便方法,这样不紧节省了重复的劳动力,而且还可以更好的优化项目,提高性能,代码如下: /* Type: 该值为类型数组,例如:

Laravel生成Word文档 - phpword

在项目实际开发或学习中,会遇到把数据导出生成word文档的需求.这里就用优雅.流行的laravel框架,来简单的教大家实现. phpword,它可以很方便的实现word文档的生成,同时可以在word中添加表格.目录.图片.超链接.页眉.页脚等功能强大. 安装phpWord 要求 强制性: PHP 5.3.3+ XML解析器扩展 Zend \ Escaper组件 Zend \ Stdlib组件 Zend \ Validator组件 可选的: -邮编扩展 - GD扩展 - XMLWriter扩展 -

php在程序中把网页生成word文档并提供下载

在这篇文章中主要解决两个问题: 1:在php中如何把html中的内容生成到word文档中 2:php把html中的内容生成到word文档中时,不居中显示问题,即会默认按照web视图进行显示. 3:php把html中的内容生成到word文档中时,相关样式不兼容问题 正文:    echo '<html xmlns:o="urn:schemas-microsoft-com:office:office"  xmlns:w="urn:schemas-microsoft-com:

POI加dom4j将数据库的数据按一定格式生成word文档

一:需求:将从数据库查处来的数据,生成word文档,并有固定的格式.(dom4j的jar包+poi的jar包) 二:解决:(1)先建立固定格式的word文档(2007版本以上),另存成为xml文件,作为模板.(修改xml节点,添加属性,用于标示要填固定数据的节点) (2)dom4j解析模板xml文件,将文件读入内存,并把数据库数据写入内存的xml模型中 (3)利用poi将内存中的含有数据库内容的xml模型转换成word内存模型,利用输出流输出word文档 三:DEMO [1]模板的word文档