質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

UTF-8

UTF-8は8ビット符号単位の文字符号化形式及び文字符号化スキームです。データ交換方式、ファイル形式としては、一般的にUTF-8が使われる傾向があります。

Apache Tomcat

Apache TomcatはApache Software Foundation (ASF)で開発されたオープンソースのWebコンテナです。

Q&A

解決済

1回答

5285閲覧

axios経由での文字化け

kanchan

総合スコア79

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

UTF-8

UTF-8は8ビット符号単位の文字符号化形式及び文字符号化スキームです。データ交換方式、ファイル形式としては、一般的にUTF-8が使われる傾向があります。

Apache Tomcat

Apache TomcatはApache Software Foundation (ASF)で開発されたオープンソースのWebコンテナです。

0グッド

0クリップ

投稿2021/08/17 09:34

nodejsやvueなどまだよくわかっていないのですが、質問いたします。

前提として、Debian10上で、Dockerを使って、nodejs+tomcat+SQLServer(Express) で動作しているシステムがあります。
インフラ面(メモリやライセンスなど)の問題で、WindowsServer上に移しています。
Windows上は、Tomcatのサービス、nodejsをサービス登録、SQLServerStandardを導入して、Dockerを外した状態です。

画面表示などは問題ないのですが、この中で、axios経由でCSVダウンロードする機能があり、文字化けします。具体的には、漢字が全て EF BF BD になっています。REPLACEMENT_CHARACTER (U+FFFD) をUTF-8に変換した後の状態です。Debian10側ではUTF-8で正しくダウンロードできています。

TomcatはUTF-8設定で、Tomcat上のbackend側でCSVデータを作成後もUTF-8として、Content-Type を text/csv で戻しているようです。
axiosはUTF-8前提で受渡しするようですが、UTF-8で受取り→JavaScriptでUTF-16になる→encodeURIComponent()でUTF-8に変換→charaset=utf-8としてダウンロード、
とこれ自体に問題はないようですが、Windows上で何かの原因か設定や環境で違う文字コードか何かになっていると思われるのですが、何かヒントでも御教授下さい。

axiosのgetに、responseType にarraybuffer,blobなど、Content-Type や encoding を渡してみても、いまいち兆しが見えません。パッケージ単位でバージョン違いとOSによる問題などであればまだいいのですが。

わかる範囲のバージョンを明記します。
Apache Maven 3.6.0
Apache Tomcat 9.0.48
JDK11
Nuxt 2.9.1

frontend側ソース frontend\pages\shuukei\sales\details.vue から抜粋 exporttoCSV(){ var api = '/api/po/detail/export-csv?'+this.params; this['$axios'].get(api).then(csv =>{ var universalBOM = "\uFEFF"; const data = csv.data; const link = document.createElement("a"); link.href = 'data:text/csv;charset=utf-8,' + encodeURIComponent(universalBOM+data); link.setAttribute("download", "明細一覧.csv"); link.click();
backend側 \backend\src\main\java\w\xxx\util\common\generator\CSVGenerator.java public <E>String generate(Table<E> table) StringWriter sWriter = new StringWriter(); : byte[] bytes = sWriter.toString().getBytes(); return new String(bytes, StandardCharsets.UTF_8);

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

まずは、axiosのレスポンスデータがShiftJISでした。

this['$axios'].get(api).then(csv =>{ ↓ this['$axios'].get(api,{ responseType: 'blob' }).then(csv =>{ const data = csv.data; link.href = 'data:text/csv;charset=utf-8,' + encodeURIComponent(universalBOM+data); ↓ const url = URL.createObjectURL(new Blob([csv.data])); link.href = url;

で、そもそもTomcatのjava側でUTF-8で返していると思いきや、

StringWriter sWriter = new StringWriter(); : byte[] bytes = sWriter.toString().getBytes(); return new String(bytes, StandardCharsets.UTF_8);

ではなく、

StringWriter sWriter = new StringWriter(); : byte[] bytes = sWriter.toString().getBytes(); return new ByteArrayInputStream( bytes );

の処理の方を使ってました。
String.getBytes()が、OSの文字セットにされてしまうため、UTF-8にしてあげる必要がありました。

StringWriter sWriter = new StringWriter(); : byte[] bytes = sWriter.toString().getBytes(); String strBytes = new String(bytes); return new ByteArrayInputStream( strBytes.getBytes("UTF-8") );

投稿2021/08/18 09:05

kanchan

総合スコア79

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問