如何使用php獲得文檔中圖片的解析

來源:互聯網
上載者:User
這篇文章主要介紹了關於php解析word,獲得文檔中的圖片,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

背景

前段時間在寫一個功能:用原生php將獲得word中的內容並匯入到網站系統中。因為文檔中存在公式,圖片,表格等,因此寫的比較麻煩。

思路

大體思路是先將word中格式為doc的文檔轉化為docx,用預先處理程式將文檔中的公式轉化為swf圖片格式,將word轉化為xml格式,在獲得xml中的內容轉化為json格式。

預備知識

1. 理解xml基礎

xml是一種可延伸標記語言 (XML),是互連網資料轉送的重要工具,xml可以實現跨互連網平台而不受程式設計語言和作業系統的限制,可以說是一個擁有互連網最進階別通行證的資料攜帶者。

xml是當前處理結構化文檔資訊中的技術,有助於在伺服器之間穿梭結構化出具,使得開發工作者可以更加方便的控制資料的儲存和傳輸

xml用於標記電子檔案使其具有結構性的標記語言,可用來標記資料,定義資料類型,是一種允許使用者對自己的標記語言進行定義的源語言。它是標準通用語言的子集,非常適合web傳輸。

2. word的兩種不同的儲存方式

word文檔的兩種儲存格式:doc和docx

doc:習慣上被稱為word,採用二進位儲存資料

docx:也就是word2007,採用xml儲存資料

那麼尾碼明明是docx格式的,為什麼成xml格式了?

選擇一個test.docx,將尾碼名改為.zip,然後進行解壓,得到下面的目錄結構:

所以你認為的docx文檔,其實是一個壓縮檔~

3. 瞭解DOM和PHP DOM XML解析

DOM提供了針對html和xml文檔的標準對象集,以及用於訪問和操作這些文檔的標準介面。XML DOM是為文檔定義標準的對象集。使用PHP DOM擴充可以實現PHP對DOM樹的一系列操作。

使用PHP DOM讀取一個XML文檔:

test.xml:

<?xml version="1.0" encoding="utf-8"?><teststore><test>    <name>php dom test</name>    <author>test-one</author></test><test>    <title>php dom test 2</title>    <author>test-two</author></test></teststore>

test.php:

<?php    $doc = new DOMDocument();    $doc->load("test.xml");    //擷取標籤對象    $book=$doc->getElementsByTagName("test");    //輸出第一個中的值    echo $book->item(0)->nodeValue;        echo "<br>----------------<br>";        $title=$doc->getElementsByTagName("name");        echo $title->item(0)->nodeValue;        echo "<br>----------------<br>";    //遍曆所有book標籤中的內容    foreach ($book as $note)    {            echo $note->nodeValue;            echo "<br>";    }

結果:

4. word中xml的定義格式

word中的資料是怎麼定義的呢??

我們只會介紹連個l兩個檔案/檔案夾:

一個檔案是word/document.xml,這個檔案定義了word整個文檔的內容。

另一個檔案夾是word/media,這個檔案夾存放著文檔的多媒體內容,換句話說文檔中所有的圖片,音頻視頻都是在這個檔案夾下存放。

document.ml中的整體結構定義:

<w:document mc:ignorable="w14 w15 wp14" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" xmlns:wpscustomdata="http://www.wps.cn/officeDocument/2013/wpsCustomData">    <w:body>        <w:p>            <w:ppr>                <w:pstyle w:val="2">                </w:pstyle>                <w:keepnext w:val="0">                </w:keepnext>                <w:keeplines w:val="0">                </w:keeplines>                <w:widowcontrol>                </w:widowcontrol>                <w:suppresslinenumbers w:val="0">                </w:suppresslinenumbers>                <w:pbdr>                    <w:top w:color="auto" w:space="0" w:sz="0" w:val="none">                    </w:top>                    <w:left w:color="auto" w:space="0" w:sz="0" w:val="none">                    </w:left>                    <w:bottom w:color="auto" w:space="0" w:sz="0" w:val="none">                    </w:bottom>                    <w:right w:color="auto" w:space="0" w:sz="0" w:val="none">                    </w:right>                </w:pbdr>

文檔段落內容:

<w:p>            <w:ppr>                <w:pstyle w:val="2">                </w:pstyle>                <w:keepnext w:val="0">                </w:keepnext>                <w:keeplines w:val="0">                </w:keeplines>                <w:widowcontrol>                </w:widowcontrol>                <w:suppresslinenumbers w:val="0">                </w:suppresslinenumbers>                <w:pbdr>                    <w:top w:color="auto" w:space="0" w:sz="0" w:val="none">                    </w:top>                    <w:left w:color="auto" w:space="0" w:sz="0" w:val="none">                    </w:left>                    <w:bottom w:color="auto" w:space="0" w:sz="0" w:val="none">                    </w:bottom>                    <w:right w:color="auto" w:space="0" w:sz="0" w:val="none">                    </w:right>                </w:pbdr>                <w:shd w:fill="FAFAFA" w:val="clear">                </w:shd>                <w:spacing w:after="150" w:afterautospacing="0" w:before="150" w:beforeautospacing="0" w:line="378" w:linerule="atLeast">                </w:spacing>                <w:ind w:firstline="0" w:left="0" w:right="0">                </w:ind>                <w:rpr>                    <w:rfonts w:ascii="Verdana" w:cs="Verdana" w:hansi="Verdana" w:hint="default">                    </w:rfonts>                    <w:i w:val="0">                    </w:i>                    <w:caps w:val="0">                    </w:caps>                    <w:color w:val="404040">                    </w:color>                    <w:spacing w:val="0">                    </w:spacing>                    <w:sz w:val="21">                    </w:sz>                    <w:szcs w:val="21">                    </w:szcs>                </w:rpr>            </w:ppr>            <w:r>                <w:rpr>                    <w:rfonts w:ascii="Verdana" w:cs="Verdana" w:hansi="Verdana" w:hint="default">                    </w:rfonts>                    <w:i w:val="0">                    </w:i>                    <w:caps w:val="0">                    </w:caps>                    <w:color w:val="404040">                    </w:color>                    <w:spacing w:val="0">                    </w:spacing>                    <w:sz w:val="21">                    </w:sz>                    <w:szcs w:val="21">                    </w:szcs>                    <w:bdr w:color="auto" w:space="0" w:sz="0" w:val="none">                    </w:bdr>                    <w:shd w:fill="FAFAFA" w:val="clear">                    </w:shd>                </w:rpr>                <w:t>                    作者: Test                </w:t>            </w:r>        </w:p>

圖片內容定義:

<w:r>                <w:rpr>                    <w:rfonts w:ascii="Verdana" w:cs="Verdana" w:hansi="Verdana" w:hint="default">                    </w:rfonts>                    <w:i w:val="0">                    </w:i>                    <w:caps w:val="0">                    </w:caps>                    <w:color w:val="404040">                    </w:color>                    <w:spacing w:val="0">                    </w:spacing>                    <w:sz w:val="21">                    </w:sz>                    <w:szcs w:val="21">                    </w:szcs>                    <w:bdr w:color="auto" w:space="0" w:sz="0" w:val="none">                    </w:bdr>                    <w:shd w:fill="FAFAFA" w:val="clear">                    </w:shd>                </w:rpr>                <w:drawing>                    <wp:inline distb="0" distl="114300" distr="114300" distt="0">                        <wp:extent cx="5543550" cy="5543550">                        </wp:extent>                        <wp:effectextent b="0" l="0" r="0" t="0">                        </wp:effectextent>                        <wp:docpr descr="IMG_256" id="1" name="Picture 1">                        </wp:docpr>                        <wp:cnvgraphicframepr>                            <a:graphicframelocks nochangeaspect="1" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">                            </a:graphicframelocks>                        </wp:cnvgraphicframepr>                        <a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">                            <a:graphicdata uri="http://schemas.openxmlformats.org/drawingml/2006/picture">                                <pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">                                    <pic:nvpicpr>                                        <pic:cnvpr descr="IMG_256" id="1" name="Picture 1">                                        </pic:cnvpr>                                        <pic:cnvpicpr>                                            <a:piclocks nochangeaspect="1">                                            </a:piclocks>                                        </pic:cnvpicpr>                                    </pic:nvpicpr>                                    <pic:blipfill>                                        <a:blip r:embed="rId4">                                        </a:blip>                                        <a:stretch>                                            <a:fillrect>                                            </a:fillrect>                                        </a:stretch>                                    </pic:blipfill>                                    <pic:sppr>                                        <a:xfrm>                                            <a:off x="0" y="0">                                            </a:off>                                            <a:ext cx="5543550" cy="5543550">                                            </a:ext>                                        </a:xfrm>                                        <a:prstgeom prst="rect">                                            <a:avlst>                                            </a:avlst>                                        </a:prstgeom>                                        <a:nofill>                                        </a:nofill>                                        <a:ln w="9525">                                            <a:nofill>                                            </a:nofill>                                        </a:ln>                                    </pic:sppr>                                </pic:pic>                            </a:graphicdata>                        </a:graphic>                    </wp:inline>                </w:drawing>            </w:r>

結論:

<w:document>  定義整個文檔的開始    <w:body>    document的子節點,文檔的主體內容        <w:p>    body的子節點,一個段落,就是word文檔中的段落           <w:r>    p元素的子節點,一個Run定義了段落中具有相同格式的一段內容                <w:t>    Run元素節點的子節點,就是文檔的內容                <w:drawing>    run元素的子節點,定義了一張圖片                    <w:inline>    drawing子節點,具體應用沒有研究                    <a:graphic>     定義了圖片內容                        <pic:blipfill>    graphic文檔的子節點,定義了圖片內容的索引.

具體的說,如果用java,那麼XWPF解析docx文檔就是做xml文檔解析,獲得所有的節點並轉換成更好用的屬性提供API進行使用,在java中poi能根據這個名稱拿到圖片相對應的資源,而擷取圖片位置的關鍵也就是這裡。

但是很不幸,我用的是php~~~所以我們需要通過php的相關介面手動實現獲得圖片.

下面說一下我的具體思路:通過PHP的內建DOMDocument介面獲得docx文檔的xml節點,遍曆xml節點找到儲存圖片的節點元素,向下遍曆圖片節點紮到r:embed索引的值。因為docx文檔是一個壓縮包格式,所以通過PHP內建介面ZipArchive介面遍曆該docx文檔(實質就是遍曆.zip壓縮包),通過索引找到對應的圖片,轉換成位元據,在拼接img標籤顯示格式為base64的圖片資料。

轉換成xml:

   private $rels_xml;    private $doc_xml;        private function readZipPart($filename) {        $zip = new ZipArchive();        $_xml = 'word/document.xml';        $_xml_rels = 'word/_rels/document.xml.rels';        if (true === $zip->open($filename)) {            if (($index = $zip->locateName($_xml)) !== false) {                $xml = $zip->getFromIndex($index);            }            $zip->close();        } else die('non zip file');                if (true === $zip->open($filename)) {            if (($index = $zip->locateName($_xml_rels)) !== false) {                $xml_rels = $zip->getFromIndex($index);                                }            $zip->close();        } else die('non zip file');                $this->doc_xml = new DOMDocument();        $this->doc_xml->encoding = mb_detect_encoding($xml);        $this->doc_xml->preserveWhiteSpace = false;        $this->doc_xml->formatOutput = true;        $this->doc_xml->loadXML($xml);        $this->doc_xml->saveXML();                $this->rels_xml = new DOMDocument();        $this->rels_xml->encoding = mb_detect_encoding($xml);        $this->rels_xml->preserveWhiteSpace = false;        $this->rels_xml->formatOutput = true;        $this->rels_xml->loadXML($xml_rels);        $this->rels_xml->saveXML();            }

判斷是否為圖片節點:

if($paragraph->name === 'w:drawing') {    (strstr($ts,'…封…') != false || strstr($ts,'…線…') != false) ? $t .= '' : $t .= $this->analysisDrawing($paragraph);}

獲得圖片索引:

   private function analysisDrawing(&$drawingXml) {        while($drawingXml->read()) {            if ($drawingXml->nodeType == XMLREADER::ELEMENT && $drawingXml->name === 'a:blip') {                $rId = $drawingXml->getAttribute('r:embed');                $rIdIndex = substr($rId,3);                return $this->checkImageFormating($rIdIndex);            }        }    }

顯示壓縮包中圖片檔案:

   private function checkImageFormating($rIdIndex) {        $imgname = 'word/media/image'.($rIdIndex-8);        $zipfileName =  __DIR__.DIRECTORY_SEPARATOR.'b'.DIRECTORY_SEPARATOR.'test.docx';        $zip=zip_open($zipfileName);        while($zip_entry = zip_read($zip)) {//讀依次讀取包中的檔案            $file_name=zip_entry_name($zip_entry);//擷取zip中的檔案名稱            if(strstr($file_name,$imgname) != '' ) {                $a = ($rIdIndex-8 < 10) ? mb_substr($file_name,mb_strlen($imgname,"utf-8"),1, 'utf-8') : '';                    if($rIdIndex-8 < 10 && $a != '.') continue;                if ($enter_zp = zip_entry_open($zip, $zip_entry, "r")) {  //讀取包中檔案                    $ext = pathinfo(zip_entry_name ($zip_entry),PATHINFO_EXTENSION);//擷取圖片副檔名                    $content = zip_entry_read($zip_entry,zip_entry_filesize($zip_entry));//讀取檔案位元據                    return sprintf('<img src="data:image/%s;base64,%s">', $ext, base64_encode($content));//利用base64_encode函數轉換讀取到的位元據並輸入輸出到頁面中                }                zip_entry_close($zip_entry); //關閉zip中開啟的項目             }        }        zip_close($zip);//關閉zip檔案       }

以上就是本文的全部內容,希望對大家的學習有所協助,更多相關內容請關注topic.alibabacloud.com!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.