シフトJISのCSVを読込みテンプレートのExcelに書き込む ~ PHP
現在でも使用しているシステムの関係でシフトJISを使用していることがあると思いますが、PHPの文字コードはUnicode(UTF-8)であるため、漢字やひらがなの全角文字を読み込むと表示されない場合があります。
今回はfgetcsvとphpspreadsheetを用いたcsv読込を説明します。
a2,b2,c2
a3,b3,c3
のようなCSVデータと何も入れていないxlsxファイルを用意してください。
fgetcsv
全角文字をそのまま読み込むと「FALSE」で表示されてしまいました。これを回避するため、setlocaleとmb_convert_variablesを使います。
<?php require "d:/oss/php/php726/vendor/autoload.php"; use PhpOffice\PhpSpreadsheet\Settings; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader; use PhpOffice\PhpSpreadsheet\Writer\Xlsx as XlsxWriter; use PhpOffice\PhpSpreadsheet\Writer\CSV as CSVWriter; // Excel読込 $reader = new XlsxReader(); $spreadsheet = $reader->load('test.xlsx'); // ロケール設定 setlocale(LC_ALL, 'ja_JP.UTF-8'); // CSV読み込み $line = 0; $fp = fopen( 'test.csv', 'r' ); while( $dataRow = fgetcsv( $tmp ) ) { $line++; for($i = 0; $i < count( $dataRow ); ++$i ){ mb_convert_variables($dataRow, "UTF-8","SJIS-win"); //列、行指定 $spreadsheet->getActiveSheet()->setCellValueByColumnAndRow( $i + 1, $line, $dataRow[$i] ); } } fclose( $tmp ); // Excel出力 $writer = new XlsxWriter($spreadsheet); $writer->save('test1.xlsx');
Window7ではこれで日本語が表示されたのですが、Windows10ではA1の日本語のセルが「あ」ですがB1のセルは「縺」になってしまいました。2列目移行がうまく変換されないようです。
シフトJISのファイルをfgetcsvで読み込むと文字化けしてしまう場合は、一旦UTF-8の文字コードのファイルに文字コードを変換して出力してからfgetcsvで読み込みこむ方法があります。
<?php require "d:/oss/php/php726/vendor/autoload.php"; use PhpOffice\PhpSpreadsheet\Settings; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader; use PhpOffice\PhpSpreadsheet\Writer\Xlsx as XlsxWriter; use PhpOffice\PhpSpreadsheet\Writer\CSV as CSVWriter; // Excel読込 $reader = new XlsxReader(); $spreadsheet = $reader->load('test.xlsx'); // ロケール設定 setlocale(LC_ALL, 'ja_JP.UTF-8'); // 文字コード変換とtmpファイル書き込み $fdata = file_get_contents('test.csv'); $fdata = mb_convert_encoding($fdata, 'UTF-8', 'SJIS-win'); $tmp = tmpfile(); fwrite($tmp, $fdata); rewind($tmp); // CSV読み込み $line = 0; while( $dataRow = fgetcsv( $tmp ) ) { $line++; for($i = 0; $i < count( $dataRow ); ++$i ){ //列、行指定 $spreadsheet->getActiveSheet()->setCellValueByColumnAndRow( $i + 1, $line, $dataRow[$i] ); } } fclose( $tmp ); // Excel出力 $writer = new XlsxWriter($spreadsheet); $writer->save('test2.xlsx');
phpspreadsheet
phpspreadsheetでもcsvを読み込めます。
<?php require "d:/oss/php/php726/vendor/autoload.php"; use PhpOffice\PhpSpreadsheet\Settings; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader; use PhpOffice\PhpSpreadsheet\Writer\Xlsx as XlsxWriter; use PhpOffice\PhpSpreadsheet\Reader\CSV as CSVReader; // Excel読込 $reader = new XlsxReader(); $spreadsheet = $reader->load('test1.xlsx'); // CSV読込 $reader2 = new CSVReader(); $reader2->setInputEncoding('SJIS'); $spreadsheetcsv = $reader2->load('test2.csv'); $arrayData = $spreadsheetcsv->getActiveSheet()->toArray(); $spreadsheet->getActiveSheet()->fromArray($arrayData,NULL,'A1'); // Excel出力 $writer = new XlsxWriter($spreadsheet); $writer->save('test3.xlsx');
setInputEncodeingをしないで実行すると、全角文字のセルは書き込まれませんので、日本語を使う場合はいれておいてください。
しかし、エラーがでてしまいます。
エラーのファイルと行数が出ているのでcsv.phpのソースファイルを変更します。
{
// Check if file exists
try {
$this->openFile($pFilename);
} catch (Exception $e) {
return false;
}fclose($this->fileHandle);$type = mime_content_type($pFilename);
$supportedTypes = [
'text/csv’,
'text/plain’,
'inode/x-empty’,
];return in_array($type, $supportedTypes, true);
}
{
// Check if file exists
try {
$this->openFile($pFilename);
} catch (Exception $e) {
return false;
}fclose($this->fileHandle);// $type = mime_content_type($pFilename);
// $supportedTypes = [
// 'text/csv’,
// 'text/plain’,
// 'inode/x-empty’,
// ];// return in_array($type, $supportedTypes, true);
return True;
}
これで簡単にexcelテンプレートにcsvのデータを入れることができます。
ディスカッション
コメント一覧
まだ、コメントがありません