準備の整ったライブラリなしでPHPでxlsxを解析する

まず、すべての側面から吸い込まれた質問に私が1000回戻った問題について説明します:愚かなマネージャー-プログラマーと相談することなく-xls(x)からサイトにデータをアップロードすることを顧客に約束しました。



すべては問題ありませんが、顧客のホストは実行用に64 MBのメモリを提供し、フォーマットせずにExelクライアントのファイルの重量がそれぞれ10〜15 MBになることを気にしませんでした。メモリ。

猫の下の解決策は5mbにかろうじて達した。



前提条件:

1.インターネットカタログの商品に関するデータを含む10〜20枚のシートのExel文書があります。 各シートの見出しは「名前」、「価格」などです。 +追加 40列の特性-および「y-excel-centimeter-scroller」の量の実際のデータ。

2. CSVは使用できません。 すべての顧客のデータは既にExelにあり、彼はそれを保存しません...彼らはここで約束しました。

3. Spreadsheet_Excel_Writerは 、普遍性がないため捨てられますが、それについて多くのことが書かれています。 メモリテストに関するコメントを待っています。

4.驚くべきことに、Googleはユニバーサルソリューションを提供していませんでした。 確かにPHP * nixでこのような問題に遭遇した人はいないでしょう。私は驚きました。



解決策:

Googleから丁寧に提供されたさまざまな方法を整理した後、 仕様を読むことにしました(ええ、父が教えてくれた...)。 そこにあるキーワードはOpen XMLに基づいており、ZIP圧縮使用して、すぐに顧客に電話をかけ、会話をxlsxに変えました。 結局21世紀! なぜ古いものをつかむのでしょう! 将来は片足で立つ必要があります!」



さらに、アルゴリズムは次のとおりです。ファイルを受け入れ、解凍し、結果を注意深く調べます。

完全にインベントリを作成する必要がありますが、[xl]ディレクトリの内容、特に/ xl / worksheets /およびファイル/xl/sharedStrings.xmlに最も関心があります。

ファイル/xl/workbook.xmlにはシートの説明が含まれていますが、 シートの名前を収集するタスクが成立しなかったため、この項目はスキップします。 必要に応じて、難しくないことを理解してください。



/xl/sharedStrings.xml



... <si> <t></t> </si> <si> <t></t> </si> <si> <t></t> </si> <si> <t>URL</t> </si> <si> <t>!</t> </si> <si> <t>!</t> </si> <si> <t>~1, 220-240 , 50 </t> </si> ...
      
      





といった具合です。 ソースドキュメントのセル内のテキストデータを表します。 すべてのシートから! 今のところ、このデータを配列に収集するだけです。

  $xml = simplexml_load_file(PATH . '/upload/xls_data/xl/sharedStrings.xml'); $sharedStringsArr = array(); foreach ($xml->children() as $item) { $sharedStringsArr[] = (string)$item->t; }
      
      







/ xl /ワークシート/

これは、「sheet1.xml」タイプのファイルとこれらのシートの説明を含むディレクトリです。 具体的には、各ファイルで、コンテンツとその子<row ...>に関心があります。

 ... <sheetData> ... <row r="1" spans="1:43" ht="48.75" customHeight="1" x14ac:dyDescent="0.2"> <cr="A1" s="1" t="s"> <v>0</v> </c> <cr="B1" s="1" t="s"> <v>1</v> </c> <cr="C1" s="2" t="s"> <v>2</v> </c> <cr="E2" s="12"> <v>2</v> </c> <cr="F2" s="12"/> .... </row> <row r="2" spans="1:43" ht="13.5" customHeight="1" x14ac:dyDescent="0.2"> ... </sheetData> ...
      
      





比較と実験の方法を使用して、セル内の属性[t = "s"](明らかにtype = string)は、sharedStrings.xmlファイルから値を取得することを示しています。 ポインター-値-$ sharedStringsArrの要素番号。 指定しない場合、値自体をセルの値として使用します。



収集するもの:

  $handle = @opendir(PATH . '/upload/xls_data/xl/worksheets'); $out = array(); while ($file = @readdir($handle)) { //      /xl/worksheets/ if ($file != "." && $file != ".." && $file != '_rels') { $xml = simplexml_load_file(PATH . '/upload/xls_data/xl/worksheets/' . $file); //   $row = 0; foreach ($xml->sheetData->row as $item) { $out[$file][$row] = array(); //    $cell = 0; foreach ($item as $child) { $attr = $child->attributes(); $value = isset($child->v)? (string)$child->v:false; $out[$file][$row][$cell] = isset($attr['t']) ? $sharedStringsArr[$value] : $value; $cell++; } $row++; } } } var_dump($out);
      
      







出力では、すでに自由に作業できる多次元配列を取得するか、データベースにデータをすぐにアップロードできます-これは全員の個人的なビジネスです。



結論として、xlsxは仕様を実際には理解しておらず、特定のxlsxドキュメントでのみタスクを完了したと言います。 結局、式と画像(t = "i"?)を書く必要があります。 このような問題に遭遇したとき、私は確かにそれを説明しますが、今のところ、xslxからテキストデータを収集するための要求の厳しいシステムアルゴリズムを紹介します。 需要があることを願っています、なぜなら これを求めて会いませんでした。



PSタグを配置するだけで、大きなExcelファイルを操作できます 。 グーグルではなく工場を手に入れる必要がありました。多くの時間を節約できました。



UPD:

空のセルは、<c>に<v>パラメーターがないこと、または<c>自体がないことで表されることがわかりました。 属性「r」を確認する必要があります。

  <cr="A1" s="1" t="s"/> <cr="B1" s="1" t="s"> <v>1</v> </c> <!--   1--> <cr="D1" s="2" t="s"> <v>2</v> </c> <cr="E1" s="12"/>
      
      





可能であれば修正します。



All Articles