phpword 创建多个对象链接到同一 excel 文件中的不同工作表

问题描述 投票:0回答:0

我使用 phpword 模板处理器创建了多个链接到同一个 excel 文件的不同工作表的对象。我在模板 processor.php 中创建了自定义函数来创建指向工作表的对象链接。

 public function setObject($search,$fileInfo,$id){
    $xmlWriter = new XMLWriter();
    /*
        fileInfo array
        name->''
        sheet->''
        range->':'
    */
    /*
    id array
    objectId->
    rIdObject->
    rIdImage->
    */
    $file= $fileInfo['name'];
    $fileNameParts = explode('.', $file);
    $ext = end($fileNameParts); 
    if($ext=='xls'){
        $progId='Excel.Sheet.8';
    }
    elseif($ext=='xlsx'){
        $progId='Excel.Sheet.12';
    }
    else{
        $progId='Package';
    }
    $sheet=preg_replace("/\\\\/","/",$file).'!'.$fileInfo['sheet'].'!'.$fileInfo['range'];
    //relationship excel file
    $xmlExcObjectRelation = "<Relationship Id=\"{$id["rIdObject"]}\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject\" Target=\"$sheet\" TargetMode=\"External\"/>";
    $this->tempDocumentRelations[$this->getMainPartName()] = str_replace('</Relationships>', $xmlExcObjectRelation, $this->tempDocumentRelations[$this->getMainPartName()]) . '</Relationships>';
    //relationship thumbnail excel file
    $this->zipClass->pclzipAddFile('vendor/phpoffice/phpword/src/PhpWord/resources/xls.png', 'word/media/' . 'xls.png');
    $xmliconRelation="<Relationship Id=\"{$id["rIdImage"]}\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/xls.png\"/>";            
    $this->tempDocumentRelations[$this->getMainPartName()] = str_replace('</Relationships>', $xmliconRelation, $this->tempDocumentRelations[$this->getMainPartName()]) . '</Relationships>';
    
    //register content type
    if(strpos($this->tempDocumentContentTypes, "xls") === false){
        $excelXlsContentType="<Default Extension=\"xls\" ContentType=\"application/vnd.ms-excel\"/>";
        $this->tempDocumentContentTypes = str_replace('</Types>', $excelXlsContentType , $this->tempDocumentContentTypes).'</Types>';        
    }
    if(strpos($this->tempDocumentContentTypes, "xlsx") === false){
        $excelXlsxContentType="<Default Extension=\"xlsx\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\"/>";
        $this->tempDocumentContentTypes = str_replace('</Types>',$excelXlsxContentType , $this->tempDocumentContentTypes).'</Types>';
    }
    if(strpos($this->tempDocumentContentTypes, "png") === false){
        $excelIconContentType="<Default Extension=\"png\" ContentType=\"image/png\"/>";
        $this->tempDocumentContentTypes = str_replace('</Types>', $excelIconContentType , $this->tempDocumentContentTypes).'</Types>';
    }
    
    
    $xmlWriter->startElement('w:r');
    $xmlWriter->startElement('w:object');
    $xmlWriter->writeAttribute('w:dxaOrig', '7247');
    $xmlWriter->writeAttribute('w:dyaOrig', '2920');

    //custom - add (v:shapetype)
    $xmlWriter->startElement('v:shapetype');
    $xmlWriter->writeAttribute('stroked','f');
    $xmlWriter->writeAttribute('filled','f');
    $xmlWriter->writeAttribute('path','m@4@5l@4@11@9@11@9@5xe');
    $xmlWriter->writeAttribute('o:preferrelative','t');
    $xmlWriter->writeAttribute('o:spt',75);
    $xmlWriter->writeAttribute('coordsize','21600,21600');
    $xmlWriter->writeAttribute('id','_x0000_t75');
    
    
        $xmlWriter->startElement('v:stroke');
        $xmlWriter->writeAttribute('joinstyle','miter');
        $xmlWriter->endElement();// v:stroke
    
        $xmlWriter->startElement('v:formulas');
            $xmlWriter->startElement('v:f');
            $xmlWriter->writeAttribute('eqn','if lineDrawn pixelLineWidth 0');
            $xmlWriter->endElement();// v:f 1
            $xmlWriter->startElement('v:f');
            $xmlWriter->writeAttribute('eqn','sum @0 1 0');
            $xmlWriter->endElement();// v:f 2   
            $xmlWriter->startElement('v:f');
            $xmlWriter->writeAttribute('eqn','sum 0 0 @1');
            $xmlWriter->endElement();// v:f 3   
            $xmlWriter->startElement('v:f');
            $xmlWriter->writeAttribute('eqn','prod @2 1 2');
            $xmlWriter->endElement();// v:f4
            $xmlWriter->startElement('v:f');
            $xmlWriter->writeAttribute('eqn','prod @3 21600 pixelWidth');
            $xmlWriter->endElement();// v:f5    
            $xmlWriter->startElement('v:f');
            $xmlWriter->writeAttribute('eqn','prod @3 21600 pixelHeight');
            $xmlWriter->endElement();// v:f6
            $xmlWriter->startElement('v:f');
            $xmlWriter->writeAttribute('eqn','sum @0 0 1');
            $xmlWriter->endElement();// v:f7
            $xmlWriter->startElement('v:f');
            $xmlWriter->writeAttribute('eqn','prod @6 1 2');
            $xmlWriter->endElement();// v:f8
            $xmlWriter->startElement('v:f');
            $xmlWriter->writeAttribute('eqn','prod @7 21600 pixelWidth');
            $xmlWriter->endElement();// v:f9
            $xmlWriter->startElement('v:f');
            $xmlWriter->writeAttribute('eqn','sum @8 21600 0');
            $xmlWriter->endElement();// v:f10
            $xmlWriter->startElement('v:f');
            $xmlWriter->writeAttribute('eqn','prod @7 21600 pixelHeight');
            $xmlWriter->endElement();// v:f11
            $xmlWriter->startElement('v:f');
            $xmlWriter->writeAttribute('eqn','sum @10 21600 0');
            $xmlWriter->endElement();// v:f12
        $xmlWriter->endElement();// v:formulas  
        $xmlWriter->startElement('v:path');
        $xmlWriter->writeAttribute('o:connecttype','rect');
        $xmlWriter->writeAttribute('gradientshapeok','t');
        $xmlWriter->writeAttribute('o:extrusionok','f');
        $xmlWriter->endElement();// v:path
        $xmlWriter->startElement('o:lock');
        $xmlWriter->writeAttribute('aspectratio','t');
        $xmlWriter->writeAttribute('v:ext','edit');
        $xmlWriter->endElement();// o:lock
    $xmlWriter->endElement();// v:shapetype
    // Icon
    $xmlWriter->startElement('v:shape');
    $xmlWriter->writeAttribute('id', '_x0000_i1025');
    $xmlWriter->writeAttribute('type', '#_x0000_t75');
    $xmlWriter->writeAttribute('style', 'width:362.25pt;height:146.25pt');
    $xmlWriter->writeAttribute('o:ole', '');

    $xmlWriter->startElement('v:imagedata');
    $xmlWriter->writeAttribute('r:id', $id['rIdImage']);
    $xmlWriter->writeAttribute('o:title', '');
    $xmlWriter->endElement(); // v:imagedata
    $xmlWriter->endElement(); // v:shape

    // Object
    $xmlWriter->startElement('o:OLEObject');
    $xmlWriter->writeAttribute('Type', 'Link');
    
    $xmlWriter->writeAttribute('ProgID', $progId);//package to Excel.Sheet.12 if object is excel xlsx, Excel.Sheet.12 of object is excel xls
    $xmlWriter->writeAttribute('ShapeID', '_x0000_i1025');
    $xmlWriter->writeAttribute('DrawAspect', 'Content');
    $xmlWriter->writeAttribute('ObjectID',$id['objectId']);
    $xmlWriter->writeAttribute('r:id',  $id['rIdObject']);
    $xmlWriter->endElement(); // o:OLEObject

    $xmlWriter->endElement(); // w:object
    $xmlWriter->endElement(); // w:r
    
    $this->replaceXmlBlock($search, '<w:p>' . $xmlWriter->getData() . '</w:p>', 'w:p');
}

然后,我将 template2.docx 中的变量替换为 excel 对象并生成 docx 文件

<?php
 require '../vendor/autoload.php';
 $templateProcessor = new \PhpOffice\PhpWord\TemplateProcessor('template2.docx');
 $fileInfo  =[
                        'name' => dirname(__FILE__).'\file2.xlsx',
                        'sheet'=> 'sheet1',
                        'range'=> 'R1C1:'.'R5C5'];
 $id        =[
                        'objectId'  => 'O_F1_1', //Object_File2_sheet1
                        'rIdObject' => 'RO_F1_1',//rIdObject_File2_sheet1
                        'rIdImage'  => 'RI_F1_1' //rIdImage_File2_sheet1
                        ];
$templateProcessor->setObject('sheet1',$fileInfo,$id);
$fileInfo2  =[

                         'name' => dirname(__FILE__).'\file2.xlsx',
                         'sheet'=> 'sheet2',
                         'range'=> 'R1C1:'.'R5C5'];
$id2            =[
                        'objectId'  => 'O_F1_2', //Object_File2_sheet2
                        'rIdObject' => 'RO_F1_2',//rIdObject_File2_sheet2
                        'rIdImage'  => 'RI_F1_2' //rIdImage_File2_sheet2 
                        ];
$templateProcessor->setObject('sheet2',$fileInfo2,$id2);
$fileInfo3  =[

                         'name' => dirname(__FILE__).'\file1.xlsx',
                         'sheet'=> 'sheet3',
                         'range'=> 'R1C1:'.'R5C5'];
$id3            =[
                        'objectId'  => 'O_F1_3', //Object_File1_sheet3
                        'rIdObject' => 'RO_F1_3',//rIdObject_File1_sheet3
                        'rIdImage'  => 'RI_F1_3' //rIdImage_File1_sheet3
                        ];
$templateProcessor->setObject('sheet3',$fileInfo3,$id3);
$templateProcessor->saveAs('output.docx');

打开文件时输出文件提示更新链接。单击确定后,仅更新第一个对象链接。我尝试从不同的文件添加工作表 3 也给出相同的结果。

我检查了链接的工作表对象。列表中仅存在第一个对象链接。

php excel word phpword createoleobject
© www.soinside.com 2019 - 2024. All rights reserved.