• PHPword解析内容支撑


    因有些功能不支持,所以新增了某些功能,以防后期变动不好变更,手动做个记录

    1. 将公式替换成指定的符号,读取到 html 后读取 xml 解析公式,根据标记符号进行替换
      文件名PhpOffice\PhpWord\Shared\XMLReader.php
    
        public function getDomFromZip($zipFile, $xmlFile)
        {
            if (file_exists($zipFile) === false) {
                throw new \Exception('Cannot find archive file.');
            }
    
            $zip = new \ZipArchive();
            $zip->open($zipFile);
            $content = $zip->getFromName($xmlFile);
            $zip->close();
    
            if ($content === false) {
                return false;
            }
            if($xmlFile === 'word/document.xml'){
                // 字符串替换,将公式替换成$Math$
                $content = preg_replace('/[\s|\S]*?<\/m:oMath>/', '$Math$', $content);
                // 后续在将$Math$标记替换为对应的处理过的mathml公式(或latex表达式、公式图片)
                
            }
    
            return $this->getDomFromString($content);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    公式转换传送大飞机来咯!

    1. 表格的单元格宽度的单位
      文件名PhpOffice\PhpWord\Reader\Word2007\AbstractPart.php
    protected function readTable(){
      //...
                    foreach ($rowNodes as $rowNode) {
                        if ('w:trPr' == $rowNode->nodeName) { // Row style
                            // @todo Do something with row style
                        } elseif ('w:tc' == $rowNode->nodeName) { // Cell
                            $cellWidth = $xmlReader->getAttribute('w:w', $rowNode, 'w:tcPr/w:tcW');
                            $cellStyle = null;
                            $cellStyleNode = $xmlReader->getElement('w:tcPr', $rowNode);
                            if (!is_null($cellStyleNode)) {
                                $cellStyle = $this->readCellStyle($xmlReader, $cellStyleNode);
                            }
                            $cell = $row->addCell($cellWidth, $cellStyle);
    
                            // ----------以下为新增部分
                            // 设置单位
                            $cellUnit = $xmlReader->getAttribute('w:type', $rowNode, 'w:tcPr/w:tcW');
                            $cell->setUnit($cellUnit);
                            // ----------以上为新增部分
    
                            $cellNodes = $xmlReader->getElements('*', $rowNode);
                            foreach ($cellNodes as $cellNode) {
                                if ('w:p' == $cellNode->nodeName) { // Paragraph
                                    $this->readParagraph($xmlReader, $cellNode, $cell, $docPart);
                                }
                            }
                        }
                    }
                }
    
      //...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    1. 内容的对齐样式
      文件名Element\AbstractContainer.php
        protected function addElement($elementName)
        {
            $elementClass = __NAMESPACE__ . '\\' . $elementName;
            $this->checkValidity($elementName);
    
            // Get arguments
            $args = func_get_args();
            $withoutP = in_array($this->container, array('TextRun', 'Footnote', 'Endnote', 'ListItemRun', 'Field'));
            if ($withoutP && ($elementName == 'Text' || $elementName == 'PreserveText')) {
                // 此处不知道为何要把样式移除,移除后的段落无alignment样式了,故把此代码注释了,不知会有何遗留问题,待发现。
                // $args[3] = null; // Remove paragraph style for texts in textrun
            }
            // ........
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    1. 新增首行缩进功能
      文件Style\Paragraph.php
        /**
         * 缩进字符
         *
         * @var integer
         * @Author 
         * @DateTime 2022-11-03
         */
        private $firstLineChars = 0; //新增属性
    
        // 修改方法
        public function getStyleValues()
        {
            $styles = array(
                // ...
                'indentation'         => $this->getIndentation(),
                // ------新增内容开始
                'firstLineChars'      => $this->getFirstLineChars(),
                // ------新增内容结束
                'spacing'             => $this->getSpace(),
                'pagination'          => array(
                    'widowControl'    => $this->hasWidowControl(),
                    'keepNext'        => $this->isKeepNext(),
                    'keepLines'       => $this->isKeepLines(),
                    'pageBreak'       => $this->hasPageBreakBefore(),
                ),
               // ...
            );
            return $styles;
        }
    
        新增方法
        /**
         * Get getFirstLineChars
         *
         * 
         */
        public function getFirstLineChars()
        {
            return $this->firstLineChars;
        }
        /**
         * Set getFirstLineChars
         *
         * 
         */
        public function setFirstLineChars($num = 0)
        {
            $this->firstLineChars = $num;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    文件Reader\Word2007\AbstractPart.php

        protected function readParagraphStyle(XMLReader $xmlReader, \DOMElement $domNode)
        {
            if (!$xmlReader->elementExists('w:pPr', $domNode)) {
                return null;
            }
    
            $styleNode = $xmlReader->getElement('w:pPr', $domNode);
            $styleDefs = array(
                'styleName'           => array(self::READ_VALUE, array('w:pStyle', 'w:name')),
                'alignment'           => array(self::READ_VALUE, 'w:jc'),
                'basedOn'             => array(self::READ_VALUE, 'w:basedOn'),
                'next'                => array(self::READ_VALUE, 'w:next'),
                'indent'              => array(self::READ_VALUE, 'w:ind', 'w:left'),
                'hanging'             => array(self::READ_VALUE, 'w:ind', 'w:hanging'),
                'firstLineChars'      => array(self::READ_VALUE, 'w:ind', 'w:firstLineChars'), //新增首行缩进
                'spaceAfter'          => array(self::READ_VALUE, 'w:spacing', 'w:after'),
                'spaceBefore'         => array(self::READ_VALUE, 'w:spacing', 'w:before'),
                'widowControl'        => array(self::READ_FALSE, 'w:widowControl'),
                'keepNext'            => array(self::READ_TRUE,  'w:keepNext'),
                'keepLines'           => array(self::READ_TRUE,  'w:keepLines'),
                'pageBreakBefore'     => array(self::READ_TRUE,  'w:pageBreakBefore'),
                'contextualSpacing'   => array(self::READ_TRUE,  'w:contextualSpacing'),
                'bidi'                => array(self::READ_TRUE,  'w:bidi'),
                'suppressAutoHyphens' => array(self::READ_TRUE,  'w:suppressAutoHyphens'),
            );
            return $this->readStyleDefs($xmlReader, $styleNode, $styleDefs);
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    1. 读取单元格的边框和颜色

    文件名PhpOffice\PhpWord\Reader\Word2007\AbstractPart.php

        /**
         * Read w:tcPr
         *
         * @param \PhpOffice\PhpWord\Shared\XMLReader $xmlReader
         * @param \DOMElement $domNode
         * @return array
         */
        private function readCellStyle(XMLReader $xmlReader, \DOMElement $domNode)
        {
            $styleDefs = array(
                'vlign'        => array(self::READ_VALUE, 'w:vAlign'),
                'textDirection' => array(self::READ_VALUE, 'w:textDirection'),
                'gridSpan'      => array(self::READ_VALUE, 'w:gridSpan'),
                'vMerge'        => array(self::READ_VALUE, 'w:vMerge'),
                'bgColor'       => array(self::READ_VALUE, 'w:shd', 'w:fill'),
            );
    
            // ------新增内容开始
            $borders = array('top', 'left', 'bottom', 'right');
            if ($xmlReader->elementExists('w:tcBorders', $domNode)) {
                foreach ($borders as $side) {
                    $ucfSide = ucfirst($side);
                    $styleDefs["border{$ucfSide}Size"] = array(self::READ_VALUE, "w:tcBorders/w:$side", 'w:sz');
                    $styleDefs["border{$ucfSide}Color"] = array(self::READ_VALUE, "w:tcBorders/w:$side", 'w:color');
                    $styleDefs["border{$ucfSide}Style"] = array(self::READ_VALUE, "w:tcBorders/w:$side", 'w:val');
                }
            }
            // ------新增内容结束
    
            return $this->readStyleDefs($xmlReader, $domNode, $styleDefs);
        }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    1. 解析图片宽度
      namespace PhpOffice\PhpWord\Reader\Word2007\AbstractPart.php;
        protected function readRunChild(XMLReader $xmlReader, \DOMElement $node, AbstractContainer $parent, $docPart, $paragraphStyle = null, $fontStyle = null)
        {
            if ($node->nodeName == 'w:drawing') {
                if (!is_null($target)) {
                    if(strpos($target,'wmf') === false){
                        // 2022/12/28 日新增读取图片宽度
                        $imgShowWidth = $xmlReader->getAttribute('cx', $node, 'wp:inline/wp:extent');
                        if($imgShowWidth == null){
                            $imgShowWidth = $xmlReader->getAttribute('cx', $node, 'wp:anchor/wp:extent');
                        }
    
                        $imageSource = "zip://{$this->docFile}#{$target}";
                        $parent->addImage($imageSource, null, false, $name,$imgShowWidth);
                    }else{
                        $textContent = "{error:不支持mathtype}";
                        $parent->addText($textContent, $fontStyle, $paragraphStyle);
                    }
                    
                }
            }
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
  • 相关阅读:
    python基础之序列类型的方法——列表&元组
    PsychoPy Coder实现心理学小实验
    HTTP常见面试题(小林coding版总结)
    F. ATM and Students(思维 + 二分 + 线段树/RMQ)
    接口测试 —— jmeter与数据库的操作
    抖音在线点赞任务发布接单运营平台PHP网站源码多个支付通道+分级会员制度,附带系统搭建教程
    一图了解es6常用数据迭代函数map,filter,fill,reduce
    IO流之File类
    内网渗透之内网信息收集(五)
    Google Earth Engine(GEE)——全球人类居住区网格数据 1975-1990-2000-2014 (P2016)
  • 原文地址:https://blog.csdn.net/Golderant/article/details/133141508