[{"data":1,"prerenderedAt":566},["ShallowReactive",2],{"article-phpspredsheet-rich-text":3},{"id":4,"title":5,"body":6,"category":554,"createdAt":556,"description":557,"extension":558,"index":559,"meta":560,"navigation":50,"path":561,"publish":50,"seo":562,"series":559,"seriesTitle":559,"stem":563,"tag":564,"thumbnail":559,"updatedAt":559,"__hash__":565},"articles\u002Farticles\u002Fphpspredsheet-rich-text.md","Phpspreadsheetで書式があるとgetValue()で文字を取得できない",{"type":7,"value":8,"toc":552},"minimark",[9,21,87,101,104,469,477,490,498,511,545,548],[10,11,12,13,20],"p",{},"こんにちはjunです。PHPでエクセルをアップロードして、データを取得するという機能を実装する際に",[14,15,19],"a",{"href":16,"rel":17},"https:\u002F\u002Fphpspreadsheet.readthedocs.io\u002Fen\u002Flatest\u002F",[18],"nofollow","Phpspreadsheet","を使用することが多いと思います。アップロードされたエクセルを以下の様にしてセルの値を取得することができます。",[22,23,28],"pre",{"className":24,"code":25,"language":26,"meta":27,"style":27},"language-php shiki shiki-themes material-theme-ocean","use \\PhpOffice\\PhpSpreadsheet\\IOFactory;\nuse \\PhpOffice\\PhpSpreadsheet\\Shared\\Date;\n\n\u002F\u002F $fileはエクセルファイル\n$spreadsheet = IOFactory::load($file);\n$worksheet = $spreadsheet->getSheetByName('Sheet1');\n\n\u002F\u002F A1のセルのデータを取得する\n$workSheet->getCell(\"A1\")->getValue();\n","php","",[29,30,31,39,45,52,58,64,70,75,81],"code",{"__ignoreMap":27},[32,33,36],"span",{"class":34,"line":35},"line",1,[32,37,38],{},"use \\PhpOffice\\PhpSpreadsheet\\IOFactory;\n",[32,40,42],{"class":34,"line":41},2,[32,43,44],{},"use \\PhpOffice\\PhpSpreadsheet\\Shared\\Date;\n",[32,46,48],{"class":34,"line":47},3,[32,49,51],{"emptyLinePlaceholder":50},true,"\n",[32,53,55],{"class":34,"line":54},4,[32,56,57],{},"\u002F\u002F $fileはエクセルファイル\n",[32,59,61],{"class":34,"line":60},5,[32,62,63],{},"$spreadsheet = IOFactory::load($file);\n",[32,65,67],{"class":34,"line":66},6,[32,68,69],{},"$worksheet = $spreadsheet->getSheetByName('Sheet1');\n",[32,71,73],{"class":34,"line":72},7,[32,74,51],{"emptyLinePlaceholder":50},[32,76,78],{"class":34,"line":77},8,[32,79,80],{},"\u002F\u002F A1のセルのデータを取得する\n",[32,82,84],{"class":34,"line":83},9,[32,85,86],{},"$workSheet->getCell(\"A1\")->getValue();\n",[10,88,89,92,93,96,97,100],{},[29,90,91],{},"getCell()","の引数を指定して再帰的に全ての列の値を取得して配列にするみたいなこともできるので、エクセルを用いてwebアプリへのデータ入力ができます。最初は",[29,94,95],{},"getValue()","を用いて問題なくセルの文字を取得できていました。しかしある日、お客さんから「このエクセルを読み取らせると変な文字が表示されます」という問い合わせをいただきました。サーバーにアップしたエクセルの内容を上記の様に取得してブラウザに表示するということをやっていたのですが、確かに",[29,98,99],{},"{}","という謎の文字がありました。",[10,102,103],{},"デバッグログを見てみると下記の様に一部の値がインスタンスとなっていました。",[22,105,107],{"className":24,"code":106,"language":26,"meta":27,"style":27},"array(\n'name' => \n  PhpOffice\\PhpSpreadsheet\\RichText\\RichText::__set_state(array(\n     'richTextElements' => \n    array (\n      0 => \n      PhpOffice\\PhpSpreadsheet\\RichText\\TextElement::__set_state(array(\n         'text' => 'テスト',\n      )),\n      1 => \n      PhpOffice\\PhpSpreadsheet\\RichText\\Run::__set_state(array(\n         'font' => \n        PhpOffice\\PhpSpreadsheet\\Style\\Font::__set_state(array(\n           'name' => '游ゴシック',\n           'size' => 12.0,\n           'bold' => false,\n           'italic' => false,\n           'superscript' => false,\n           'subscript' => false,\n           'underline' => 'none',\n           'strikethrough' => false,\n           'color' => \n          PhpOffice\\PhpSpreadsheet\\Style\\Color::__set_state(array(\n             'argb' => 'FF000000',\n             'hasChanged' => false,\n             'isSupervisor' => false,\n             'parent' => NULL,\n             'parentPropertyName' => NULL,\n          )),\n           'colorIndex' => NULL,\n           'isSupervisor' => false,\n           'parent' => NULL,\n           'parentPropertyName' => NULL,\n        )),\n         'text' => 'テス',\n      )),\n      2 => \n      PhpOffice\\PhpSpreadsheet\\RichText\\Run::__set_state(array(\n         'font' => \n        PhpOffice\\PhpSpreadsheet\\Style\\Font::__set_state(array(\n           'name' => '游ゴシック',\n           'size' => 12.0,\n           'bold' => false,\n           'italic' => false,\n           'superscript' => false,\n           'subscript' => false,\n           'underline' => 'none',\n           'strikethrough' => false,\n           'color' => \n          PhpOffice\\PhpSpreadsheet\\Style\\Color::__set_state(array(\n             'argb' => 'FF000000',\n             'hasChanged' => false,\n             'isSupervisor' => false,\n             'parent' => NULL,\n             'parentPropertyName' => NULL,\n          )),\n           'colorIndex' => NULL,\n           'isSupervisor' => false,\n           'parent' => NULL,\n           'parentPropertyName' => NULL,\n        )),\n         'text' => 'テスト',\n      )),\n    ),\n  )),\n)\n",[29,108,109,114,119,124,129,134,139,144,149,154,160,166,172,178,184,190,196,202,208,214,220,226,232,238,244,250,256,262,268,274,280,286,292,298,304,310,315,321,326,331,336,341,346,351,356,361,366,371,376,381,386,391,396,401,406,411,416,421,426,431,436,441,446,451,457,463],{"__ignoreMap":27},[32,110,111],{"class":34,"line":35},[32,112,113],{},"array(\n",[32,115,116],{"class":34,"line":41},[32,117,118],{},"'name' => \n",[32,120,121],{"class":34,"line":47},[32,122,123],{},"  PhpOffice\\PhpSpreadsheet\\RichText\\RichText::__set_state(array(\n",[32,125,126],{"class":34,"line":54},[32,127,128],{},"     'richTextElements' => \n",[32,130,131],{"class":34,"line":60},[32,132,133],{},"    array (\n",[32,135,136],{"class":34,"line":66},[32,137,138],{},"      0 => \n",[32,140,141],{"class":34,"line":72},[32,142,143],{},"      PhpOffice\\PhpSpreadsheet\\RichText\\TextElement::__set_state(array(\n",[32,145,146],{"class":34,"line":77},[32,147,148],{},"         'text' => 'テスト',\n",[32,150,151],{"class":34,"line":83},[32,152,153],{},"      )),\n",[32,155,157],{"class":34,"line":156},10,[32,158,159],{},"      1 => \n",[32,161,163],{"class":34,"line":162},11,[32,164,165],{},"      PhpOffice\\PhpSpreadsheet\\RichText\\Run::__set_state(array(\n",[32,167,169],{"class":34,"line":168},12,[32,170,171],{},"         'font' => \n",[32,173,175],{"class":34,"line":174},13,[32,176,177],{},"        PhpOffice\\PhpSpreadsheet\\Style\\Font::__set_state(array(\n",[32,179,181],{"class":34,"line":180},14,[32,182,183],{},"           'name' => '游ゴシック',\n",[32,185,187],{"class":34,"line":186},15,[32,188,189],{},"           'size' => 12.0,\n",[32,191,193],{"class":34,"line":192},16,[32,194,195],{},"           'bold' => false,\n",[32,197,199],{"class":34,"line":198},17,[32,200,201],{},"           'italic' => false,\n",[32,203,205],{"class":34,"line":204},18,[32,206,207],{},"           'superscript' => false,\n",[32,209,211],{"class":34,"line":210},19,[32,212,213],{},"           'subscript' => false,\n",[32,215,217],{"class":34,"line":216},20,[32,218,219],{},"           'underline' => 'none',\n",[32,221,223],{"class":34,"line":222},21,[32,224,225],{},"           'strikethrough' => false,\n",[32,227,229],{"class":34,"line":228},22,[32,230,231],{},"           'color' => \n",[32,233,235],{"class":34,"line":234},23,[32,236,237],{},"          PhpOffice\\PhpSpreadsheet\\Style\\Color::__set_state(array(\n",[32,239,241],{"class":34,"line":240},24,[32,242,243],{},"             'argb' => 'FF000000',\n",[32,245,247],{"class":34,"line":246},25,[32,248,249],{},"             'hasChanged' => false,\n",[32,251,253],{"class":34,"line":252},26,[32,254,255],{},"             'isSupervisor' => false,\n",[32,257,259],{"class":34,"line":258},27,[32,260,261],{},"             'parent' => NULL,\n",[32,263,265],{"class":34,"line":264},28,[32,266,267],{},"             'parentPropertyName' => NULL,\n",[32,269,271],{"class":34,"line":270},29,[32,272,273],{},"          )),\n",[32,275,277],{"class":34,"line":276},30,[32,278,279],{},"           'colorIndex' => NULL,\n",[32,281,283],{"class":34,"line":282},31,[32,284,285],{},"           'isSupervisor' => false,\n",[32,287,289],{"class":34,"line":288},32,[32,290,291],{},"           'parent' => NULL,\n",[32,293,295],{"class":34,"line":294},33,[32,296,297],{},"           'parentPropertyName' => NULL,\n",[32,299,301],{"class":34,"line":300},34,[32,302,303],{},"        )),\n",[32,305,307],{"class":34,"line":306},35,[32,308,309],{},"         'text' => 'テス',\n",[32,311,313],{"class":34,"line":312},36,[32,314,153],{},[32,316,318],{"class":34,"line":317},37,[32,319,320],{},"      2 => \n",[32,322,324],{"class":34,"line":323},38,[32,325,165],{},[32,327,329],{"class":34,"line":328},39,[32,330,171],{},[32,332,334],{"class":34,"line":333},40,[32,335,177],{},[32,337,339],{"class":34,"line":338},41,[32,340,183],{},[32,342,344],{"class":34,"line":343},42,[32,345,189],{},[32,347,349],{"class":34,"line":348},43,[32,350,195],{},[32,352,354],{"class":34,"line":353},44,[32,355,201],{},[32,357,359],{"class":34,"line":358},45,[32,360,207],{},[32,362,364],{"class":34,"line":363},46,[32,365,213],{},[32,367,369],{"class":34,"line":368},47,[32,370,219],{},[32,372,374],{"class":34,"line":373},48,[32,375,225],{},[32,377,379],{"class":34,"line":378},49,[32,380,231],{},[32,382,384],{"class":34,"line":383},50,[32,385,237],{},[32,387,389],{"class":34,"line":388},51,[32,390,243],{},[32,392,394],{"class":34,"line":393},52,[32,395,249],{},[32,397,399],{"class":34,"line":398},53,[32,400,255],{},[32,402,404],{"class":34,"line":403},54,[32,405,261],{},[32,407,409],{"class":34,"line":408},55,[32,410,267],{},[32,412,414],{"class":34,"line":413},56,[32,415,273],{},[32,417,419],{"class":34,"line":418},57,[32,420,279],{},[32,422,424],{"class":34,"line":423},58,[32,425,285],{},[32,427,429],{"class":34,"line":428},59,[32,430,291],{},[32,432,434],{"class":34,"line":433},60,[32,435,297],{},[32,437,439],{"class":34,"line":438},61,[32,440,303],{},[32,442,444],{"class":34,"line":443},62,[32,445,148],{},[32,447,449],{"class":34,"line":448},63,[32,450,153],{},[32,452,454],{"class":34,"line":453},64,[32,455,456],{},"    ),\n",[32,458,460],{"class":34,"line":459},65,[32,461,462],{},"  )),\n",[32,464,466],{"class":34,"line":465},66,[32,467,468],{},")\n",[10,470,471,472],{},"対象のエクセルのセルを見てみると文字が赤色になっていたりと装飾が当てられていました。原因がわかったので対処を行います。調査の結果似た様なissueがありました。",[14,473,476],{"href":474,"rel":475},"https:\u002F\u002Fgithub.com\u002FPHPOffice\u002FPhpSpreadsheet\u002Fissues\u002F442",[18],"RichText can not get the correct value, when one part is plain text and the other part is rich text.",[10,478,479,480,482,483,486,487,489],{},"方法としては",[29,481,95],{},"に加えて",[29,484,485],{},"getPlainText()","というメソッドを通すことで装飾されたセルの値（リッチテキスト）を取得することができます。しかし",[29,488,485],{},"には問題があり、なんとリッチテキストでない値に適用すると以下の様エラーが発生します。",[22,491,496],{"className":492,"code":494,"language":495},[493],"language-text","Call to a member function getPlainText() on string.\n","text",[29,497,494],{"__ignoreMap":27},[10,499,500,501,503,504,506,507,510],{},"つまり、",[29,502,95],{},"した時の値がリッチテキストインスタンスであるかをチェックして",[29,505,485],{},"を適用するかを分岐させる必要があります。リッチテキストは",[29,508,509],{},"\\PhpOffice\\PhpSpreadsheet\\RichText\\RichText","というクラスなので以下の様な関数を作成すれば問題ありません。",[22,512,514],{"className":24,"code":513,"language":26,"meta":27,"style":27},"use \\PhpOffice\\PhpSpreadsheet\\RichText\\RichText;\n\nfunction getCellValue($workSheet,$cell){\n    $val = $workSheet->getCell($cell)->getValue();\n    return ($val instanceof RichText)?$val->getPlainText():$val;\n}\n",[29,515,516,521,525,530,535,540],{"__ignoreMap":27},[32,517,518],{"class":34,"line":35},[32,519,520],{},"use \\PhpOffice\\PhpSpreadsheet\\RichText\\RichText;\n",[32,522,523],{"class":34,"line":41},[32,524,51],{"emptyLinePlaceholder":50},[32,526,527],{"class":34,"line":47},[32,528,529],{},"function getCellValue($workSheet,$cell){\n",[32,531,532],{"class":34,"line":54},[32,533,534],{},"    $val = $workSheet->getCell($cell)->getValue();\n",[32,536,537],{"class":34,"line":60},[32,538,539],{},"    return ($val instanceof RichText)?$val->getPlainText():$val;\n",[32,541,542],{"class":34,"line":66},[32,543,544],{},"}\n",[10,546,547],{},"リッチテキストのインスタンスかをチェックして値を取得することでリッチテキストもプレーンテキストも対応することができました。こう考えるとやっぱりエクセルインポートなんてやめてCSVインポートにしておけばよかったなーと思っています。",[549,550,551],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":27,"searchDepth":47,"depth":47,"links":553},[],[555],"ministack","2022-02-28","書式を当てたセルから文字・値を取得する方法","md",null,{},"\u002Farticles\u002Fphpspredsheet-rich-text",{"title":5,"description":557},"articles\u002Fphpspredsheet-rich-text",[26],"vZGoVH1w7p4Zs6BmYkw-9jf7nQBYtDotePnJnccXEz4",1780987146736]