JavaScript Tips | 文字列ユーティリティ:業務用 - TSV 生成

JavaScript JavaScript
スポンサーリンク

何をしたいユーティリティか:「TSV 生成」

ここで目指すのは、業務データ(配列や配列の配列)から「TSV 文字列」を安全に生成するユーティリティです。

TSV(Tab Separated Values)は「タブ区切りテキスト」で、
Excel やスプレッドシートに貼り付けやすく、CSV よりもシンプルなルールで扱えるのが特徴です。

toTsvRow([1, "山田太郎", "営業部"]); 
// "1\t山田太郎\t営業部"

toTsv([
  [1, "山田太郎", "営業部"],
  [2, "佐藤花子", "開発部"],
]);
// "1\t山田太郎\t営業部\n2\t佐藤花子\t開発部"
JavaScript

こういう「TSV 文字列」を、毎回手書きの連結ではなく、
ユーティリティ関数に任せるのがゴールです。


TSV のルールをざっくり押さえる

区切り文字は「タブ」

CSV はカンマ , で区切りますが、TSV はタブ \t で区切ります。

1 行は「タブ区切りのフィールドの並び」で、
行と行は改行 \n で区切ります。

1\t山田太郎\t営業部\n2\t佐藤花子\t開発部

という 1 本の文字列が、2 行の TSV になります。

CSV よりエスケープがシンプル

CSV はカンマ・改行・ダブルクォートの扱いがややこしいですが、
TSV は「タブと改行だけ気をつければよい」と考えると分かりやすいです。

ただし、タブや改行がフィールドの中に入ると、列や行がずれるので、
そこはちゃんと処理する必要があります。


まずは 1 セル分の「TSV エスケープ」を考える

どんな値をどう扱うか

TSV の 1 セルに入れるとき、最低限決めておきたいルールはこれです。

  • null / undefined は空文字にする
  • 数値や日付は文字列化する
  • タブ \t はスペースに置き換える(列ズレ防止)
  • 改行はそのまま残すか、スペースにするかを決める

ここでは、「タブはスペースに置き換え」「改行はそのまま(Excel でセル内改行として見える)」という方針でいきます。


tsvEscape 関数を作る

実装コード

function tsvEscape(value) {
  if (value == null) {
    return "";
  }

  let str = String(value);

  str = str.replace(/\t/g, " ");

  return str;
}
JavaScript

重要なポイントをかみ砕いて説明する

null / undefined は空セルとして扱います。

if (value == null) {
  return "";
}
JavaScript

TSV では、空セルを表現したいことがよくあるので、
ここでは「何もない値は空文字」として扱っています。

次に、文字列化します。

let str = String(value);
JavaScript

数値でも日付でも、TSV に出すときは最終的に文字列です。
ここで一度文字列にしてしまえば、あとは文字列として処理できます。

そして、タブをスペースに置き換えます。

str = str.replace(/\t/g, " ");
JavaScript

フィールドの中にタブがあると、「列の区切り」と区別がつかなくなり、
Excel などで開いたときに列がずれます。

なので、「フィールド内のタブは禁止」と割り切って、
スペースに置き換えるのが安全です。

改行(\n\r\n)はここではそのまま残しています。
Excel で開くと「セル内改行」として表示されます。


配列から 1 行の TSV を作る

toTsvRow 関数

1 セル分のエスケープができたので、
次は「配列 → 1 行の TSV 文字列」を作る関数です。

function toTsvRow(values) {
  return values.map(tsvEscape).join("\t");
}
JavaScript

やっていることはシンプルで、

  1. 各要素を tsvEscape で安全な文字列にする
  2. タブ \t で join する

これで 1 行分の TSV ができます。

動作例

toTsvRow([1, "山田太郎", "営業部"]);
// "1\t山田太郎\t営業部"

toTsvRow([2, "佐藤\t花子", "開発部"]);
// "2\t佐藤 花子\t開発部"(タブがスペースに変わる)

toTsvRow([3, "A\nB", "総務部"]);
// "3\tA\nB\t総務部"
JavaScript

2 行目の "佐藤\t花子" は、
フィールド内のタブがスペースに変わっているのがポイントです。


2 次元配列から「TSV 全体」を作る

toTsv 関数

最後に、「行の配列 → TSV 全体の文字列」を作る関数です。

function toTsv(rows) {
  return rows.map(toTsvRow).join("\n");
}
JavaScript

ここでもやっていることはシンプルで、

  1. 各行(配列)を toTsvRow で 1 行の文字列にする
  2. 行と行を改行 \n で join する

これで、TSV ファイルとしてそのまま保存できる 1 本の文字列ができます。

動作例

const rows = [
  [1, "山田太郎", "営業部"],
  [2, "佐藤花子", "開発部"],
  [3, "A\nB", "総務部"],
];

const tsv = toTsv(rows);

/*
"1\t山田太郎\t営業部\n2\t佐藤花子\t開発部\n3\tA\nB\t総務部"
*/
JavaScript

この文字列を .tsv ファイルとして保存し、
Excel で開くと、3 行 3 列の表として表示されます。
3 行目の「A\nB」は、1 セルの中で改行されて見えます。


実務で意識してほしい設計のポイント

「TSV 生成は必ずユーティリティを通す」

文字列連結で

id + "\t" + name + "\t" + dept
JavaScript

のように書き始めると、
タブや改行が混ざった瞬間に壊れます。

「TSV に出すときは必ず tsvEscape / toTsvRow / toTsv を通す」
というルールにしておくと、列ズレ事故をかなり防げます。

タブと改行の扱いをチームで決める

ここでは「タブはスペースに置き換え」「改行は許容」という方針にしましたが、
業務によっては「改行もスペースにしたい」「改行を \\n にしたい」などの要件もあります。

例えば、改行もスペースにしたいなら、tsvEscape をこう変えられます。

function tsvEscape(value) {
  if (value == null) {
    return "";
  }

  let str = String(value);

  str = str.replace(/\t/g, " ");
  str = str.replace(/\r?\n/g, " ");

  return str;
}
JavaScript

「どこまでを許容して、どこからを潰すか」は仕様なので、
ユーティリティの中で一貫したルールにしておくのが大事です。

ヘッダ行も一緒に生成する

TSV を業務で使うときは、ヘッダ行(列名)を付けることが多いです。

const header = ["ID", "氏名", "部署"];
const body = [
  [1, "山田太郎", "営業部"],
  [2, "佐藤花子", "開発部"],
];

const tsv = toTsv([header, ...body]);
JavaScript

こうしておけば、Excel で開いたときに列名が分かりやすくなります。


少し手を動かして感覚をつかむ

コンソールで、次のようなコードを実際に打ってみてください。

tsvEscape("山田太郎");
tsvEscape("佐藤\t花子");
tsvEscape("A\nB");

toTsvRow([1, "山田太郎", "営業部"]);
toTsvRow([2, "佐藤\t花子", "開発部"]);

const rows = [
  ["ID", "氏名", "部署"],
  [1, "山田太郎", "営業部"],
  [2, "佐藤\t花子", "開発部"],
];
const tsv = toTsv(rows);
JavaScript

tsv の中身をコピーして .tsv ファイルに貼り付け、
Excel で開いてみてください。

列がずれず、タブがちゃんと区切りとして機能していること、
フィールド内のタブがスペースに変わっていることが確認できるはずです。

そのうえで、自分のプロジェクトに

export function tsvEscape(...) { ... }
export function toTsvRow(...) { ... }
export function toTsv(...) { ... }
JavaScript

を置き、

「TSV を出したくなったら必ずここを通す」

というルールを作ってみてください。
それだけで、あなたの TSV 出力は、場当たり的な文字列連結から、
業務で安心して使える「堅牢な TSV 生成ユーティリティ」に変わっていきます。

タイトルとURLをコピーしました