代码之家  ›  专栏  ›  技术社区  ›  user2552863

PHPWord如何返回word响应对象

  •  0
  • user2552863  · 技术社区  · 4 年前

    我的php symfony文档下载代码内容,我正在下载PDF和docx,我可以得到PDF响应对象作为返回,但不能返回docx响应对象。这是我下载docx的代码,

    public function getDocxBuilder()
    {
        if (is_null($this->docxBuilder)) {
            $this->docxBuilder = new \PhpOffice\PhpWord\PhpWord();
        }
    
        return $this->docxBuilder;
    }
    
    public function setMarginArray($parameterArray, $fileType)
    {
        $this->name = isset($parameterArray['name']) ? $parameterArray['name'] : 'document';
        $pageSize = isset($parameterArray['pageSize']) ? $parameterArray['pageSize'] : 'A4';
        $marginLeft = isset($parameterArray['margin_left']) ? $parameterArray['margin_left'] : ($fileType == "PDF" ? '10mm' : 600);
        $marginRight = isset($parameterArray['margin_right']) ? $parameterArray['margin_right'] : ($fileType == "PDF" ? '10mm' : 600);
        $marginTop = isset($parameterArray['margin_top']) ? $parameterArray['margin_top'] : ($fileType == "PDF" ? '10mm' : 600);
        $marginBottom = isset($parameterArray['margin_bottom']) ? $parameterArray['margin_bottom'] : ($fileType == "PDF" ? '10mm' : 600);
    
        return [
            'pageSize' => $pageSize,
            'name' => $this->name,
            'marginLeft' => $marginLeft,
            'marginRight' => $marginRight,
            'marginTop' => $marginTop,
            'marginBottom' => $marginBottom
        ];
    }
    
    public function exportDocument($parameterArray, $content)
    {
        $pageOption = $this->setMarginArray($parameterArray, $fileType = 'docx');
        $this->getDocx($content, $pageOption);
    }
    
    protected function getDocx($content, $sectionStyle)
    {
        $section = $this->getDocxBuilder()->addSection($sectionStyle);
        $content = preg_replace("/<table\s(.+?)>(.+?)<\/table>/is", "<table style=\"border: 6px #000000 solid;\">$2</table>", $content);
        $content = str_replace("<p><div style=' page-break-after:always !important;'></div></p>", "<pagebreak></pagebreak>", $content);
        $content = str_replace("&nbsp", " ", $content);
    
        header('Content-Type: application/vnd.ms-word');
        header('Content-Disposition: attachment;filename="test.docx"');
        header('Cache-Control: max-age=0');
        $objWriter = PHPWord_IOFactory::createWriter($this->docxBuilder, 'Word2007');
        $objWriter->save('php://output');
    }
    

    Word下载功能正在工作,但是,我想为我的RESTAPI返回一个Word响应对象,因为我上面的代码被返回null。我对此进行了大量搜索,但找不到如何返回php/word响应对象。

    0 回复  |  直到 4 年前
        1
  •  1
  •   Julien B.    4 年前

    如果我正确理解你的问题,你想返回一个Symfony响应文件。流式响应最适合这种情况。

    /**
     * @Route("/", name="default")
     */
    public function index(): Response
    {
        return $this->exportDocument([], 'test');
    }
    
    public function getDocxBuilder()
    {
        if (is_null($this->docxBuilder)) {
            $this->docxBuilder = new \PhpOffice\PhpWord\PhpWord();
        }
    
        return $this->docxBuilder;
    }
    
    public function setMarginArray($parameterArray, $fileType)
    {
    
        $this->name   = isset($parameterArray['name']) ? $parameterArray['name'] : 'document';
        $pageSize     = isset($parameterArray['pageSize']) ? $parameterArray['pageSize'] : 'A4';
        $marginLeft   = isset($parameterArray['margin_left']) ? $parameterArray['margin_left'] : ($fileType == "PDF" ? '10mm' : 600);
        $marginRight  = isset($parameterArray['margin_right']) ? $parameterArray['margin_right'] : ($fileType == "PDF" ? '10mm' : 600);
        $marginTop    = isset($parameterArray['margin_top']) ? $parameterArray['margin_top'] : ($fileType == "PDF" ? '10mm' : 600);
        $marginBottom = isset($parameterArray['margin_bottom']) ? $parameterArray['margin_bottom'] : ($fileType == "PDF" ? '10mm' : 600);
    
        return [
            'pageSize'     => $pageSize,
            'name'         => $this->name,
            'marginLeft'   => $marginLeft,
            'marginRight'  => $marginRight,
            'marginTop'    => $marginTop,
            'marginBottom' => $marginBottom
        ];
    }
    
    public function exportDocument($parameterArray, $content)
    {
        $pageOption = $this->setMarginArray($parameterArray, $fileType = 'docx');
        return $this->getDocx($content, $pageOption);
    }
    
    protected function getDocx($content, $sectionStyle)
    {
        $section = $this->getDocxBuilder()->addSection($sectionStyle);
        $content = preg_replace("/<table\s(.+?)>(.+?)<\/table>/is",
            "<table style=\"border: 6px #000000 solid;\">$2</table>", $content);
        $content = str_replace("<p><div style=' page-break-after:always !important;'></div></p>",
            "<pagebreak></pagebreak>", $content);
        $content = str_replace("&nbsp", " ", $content);
    
        // The latest version of PHPWord is using IOFactory from the PhpOffice\PhpWord namespace
        // instead of the PHPWord_IOFactory, you might want to change it back.
        $objWriter = IOFactory::createWriter($this->docxBuilder, 'Word2007');
    
        $response = new StreamedResponse();
        // Here we are using the $objWriter in a Callback method.
        // This way we can use php://output within a Symfony Repsonse (StreamedResponse)
        $response->setCallback(function () use ($objWriter) {
            $objWriter->save('php://output');
        });
        $response->headers->set('Content-Type', 'application/vnd.ms-word');
        $response->headers->set('Cache-Control', 'max-age=0');
        $disposition = HeaderUtils::makeDisposition(
            HeaderUtils::DISPOSITION_ATTACHMENT,
            'test.docx'
        );
        $response->headers->set('Content-Disposition', $disposition);
    
        return $response;
    }