1

私はさまざまな特殊文字を使用するプロジェクトに取り組んでいます。現在、特にアラビア語の文字に取り組んでおり、PHP からエクスポートするときに、角括弧として表示されるコードをそのまま使用して、Excel で正しく表示するのに苦労しています。エクスポートされたファイルで。

私はこれを達成するためにさまざまな方法を試しましたが、いくつかは他の方法よりも優れた結果をもたらしましたが、最終的にはすべての試みに何らかの問題があります.

いくつかの調査を行ったところ、BOM を使用した UTF-16LE としてのエンコードがこれを機能させる最も可能性の高い方法であることがわかりましたが、これまでのところ、これを実装する最善の方法を見つけることができません。


私が試したこと

以下のコードで、コードの開始時に設定した 4 つの変数に応じてコードが取ることができるいくつかのルートがあることがわかります。これらのトグルを入れ始めたので、コードを作成しなくてもさまざまな方法を試すことができます。読めない。

現時点では、コードにある設定で CSV をエクスポートできますが、アラビア文字が四角いボックスとして表示されます。VS Code で CSV を表示すると、エンコーディング タイプを認識できないことがわかります。デフォルトでUTF-8になり、BOMで正常にエクスポートされたことも通知されます。

UTF-16LE への切り替えは簡単なようで、実際に成功しましたが、BOM としてエクスポートしてから、UTF-16LE に戻す方法を見つけることができませんでした。最終的に、私はあまりにも長い間コードを見つめてきたと思います。修正は非常に迅速になると思いますが、現時点ではそれを見ることができません。SO の質問で問題を説明することで、問題が何であるかを理解できると思いますが、これまでのところ何もありません。

array_walkを使用してカンマ区切り、タブ区切りでエクスポートしようとしましiconvたが、値を UTF-16LE に変換するために、エクスポートの開始時におよびをmb_convert_encode使用して、ヘッダーに Content-Encoding と Content-Type を設定しようとしましたBOM に変換します (以下の現在のバージョンが最適に動作しているようです)。\xEF\xBB\xBFchr(255) . chr(254)

また、私のコードで両方を使用したことがわかり、どちらfwritefputcsv最もうまく機能fputcsvしているか、現時点で最もうまく機能しているように見えるかを確認できます。

任意のポインタをいただければ幸いです - 説明が必要な場合は、コメントで質問してください。


これまでの私のコード

function convertToUTF16LE(&$value, $key) {
    $value = iconv('UTF-8', 'UTF-16LE', $value);
}

$fput = true;
$iconv = true;
$UTF16 = true;
$walk = false;

if($UTF16 == true) {
    header('Content-Encoding: UTF-16LE');
    header('Content-type: text/csv; charset=UTF-16LE');
} else {
    header('Content-Encoding: UTF-8');
    header('Content-Type: text/csv; charset=UTF-8');
}

header('Content-Disposition: attachment; filename="file.csv"');
header("Content-Transfer-Encoding: binary");
header('Accept-Ranges: bytes');
header("Cache-control: private");
header('Pragma: private');
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");

$filesize = 0;
$delimiter = '\t';
$prefix = '';

$output = fopen('php://output', 'w');

$headings = array("IATA Code", "Country", "Country Code", "English Name", "Current Name", "Is Primary?", "New Name");
if($UTF16 == true && $walk == true) array_walk($headings, 'convertToUTF16LE');

if($UTF16 == true) $prefix = "\xEF\xBB\xBF"; // chr(255) . chr(254);
$filesize += fwrite($output, $prefix . 'sep=' . $delimiter . PHP_EOL);

if($fput == true) {

    $filesize += fputcsv($output, $headings, $delimiter, '"', "\0");

} else {

    $headings_data = implode($delimiter, $headings);
    $filesize += fwrite($output, $headings_data . PHP_EOL);

}

// This variable exists but the data has not been included in this code.
foreach($data_to_export as $row) {
    foreach($row as $k => $v) {
        if($UTF16 == true) $row[$k] = ($iconv == true ? iconv('UTF-8', 'UTF-16LE', $v) : mb_convert_encoding($v, 'UTF-16LE', 'auto'));
    }

    if($UTF16 == true && $walk == true) array_walk($row, 'convertToUTF16LE');

    if($fput == true) {

        $filesize += fputcsv($output, array(
            $row['code'],
            $row['country'],
            $row['countrycode'],
            $row['english_name'],
            $row['name'],
            ($row['isprimary'] ? 'Y' : 'N'),
            ''
        ), $delimiter, '"', '\0');

    } else {

        $row_data = implode($delimiter, $row);
        $filesize += fwrite($output, $row_data . PHP_EOL);

    }

}

header("Content-Length: ".$filesize);
exit(0);
4

0 に答える 0