📊 Node-RED CSVノード ガイド

このガイドでは、Node-REDのCSVノードについて、初心者の方でも理解できるように詳しく説明します。

📚 1. CSVノードとは?

🤔 「CSV」って何?

CSV(Comma-Separated Values)とは、データをカンマで区切って並べたテキスト形式で、Excelなどの表計算ソフトでよく使われます。 CSVノードは、このCSV形式のテキストとJavaScriptオブジェクトを相互変換するノードです。 日常生活で例えると、Excelの表データと個別のカードを相互変換するオフィス作業のようなものです。

📋 オフィスでのデータ変換作業に例えると:

↔️ 2つの変換方向

パース

CSV → オブジェクト

CSV文字列を
JavaScriptオブジェクトに変換

生成

オブジェクト → CSV

JavaScriptオブジェクトを
CSV文字列に変換

📦 基本的な動作

Inject Template
(CSV)
CSV Debug

CSVノードは入力データの型を自動判定します。文字列が入力されればパースオブジェクトが入力されれば生成を行います。

📊 CSV → オブジェクト変換の例

入力(CSV文字列)
Apple,100,Canada
Orange,120,USA
Banana,80,Philippines
↓ CSVノード(パース)↓
出力(オブジェクト)
{col1:"Apple", col2:"100", col3:"Canada"}
{col1:"Orange", col2:"120", col3:"USA"}
{col1:"Banana", col2:"80", col3:"Philippines"}

📊 オブジェクト → CSV変換の例

入力(オブジェクト)
{kind:"Apple", price:100, origin:"Canada"}
↓ CSVノード(生成)↓
出力(CSV文字列)
Apple,100

⚙️ 2. CSVノードの設定詳細

1行ずつ メッセージ出力

CSVの各行を個別のメッセージとして順番に送信

msg.parts付きで Split的に出力

配列 一括出力

全行をオブジェクト配列として1つのメッセージで送信

全データを配列で まとめて出力

📋 設定項目一覧(パース時)

設定項目 説明
パーサ CSV解析の準拠仕様 RFC 4180 / legacy
区切り文字 列を区切る文字 , (カンマ)、\t (タブ)、; (セミコロン)
列名 出力オブジェクトのキー名 kind,price,origin
1行目に列名を含む CSVの先頭行をカラム名として使用 チェックON/OFF
出力 1行ずつメッセージ or 配列で一括 行毎にメッセージを分割 / 配列化した1つのメッセージ
最初の〜行を無視する 先頭から無視する行数 0, 1, 2...
数値を変換する 数値文字列を数値型に変換 チェックON/OFF
空の文字を含む 空のフィールドを含めるか チェックON/OFF
null値を含む null値を含めるか チェックON/OFF

📋 設定項目一覧(生成時)

設定項目 説明
列名 出力するプロパティとその順序 kind,price(originは除外)
出力 カラム名を先頭行に出力するか カラムヘッダを送信しない / カラムヘッダを常に送信する / ヘッダを一度だけ送信する
改行コード 行末の改行文字 \n (LF) / \r\n (CRLF)

🎯 入力メッセージで制御できるプロパティ

プロパティ 説明
msg.payload CSV文字列(パース)またはオブジェクト(生成) "a,b,c" / {a:1, b:2}
msg.columns 動的にカラム名を指定 "kind,price,origin"
msg.reset ヘッダー出力をリセット(生成時) true

🎯 3. 実用的な使用パターン

📥 サンプルフローのインポート方法:

  1. 下のサンプルフローJSONをコピー
  2. Node-REDエディタで メニュー → 読み込み を選択
  3. JSONをペーストして「読み込み」をクリック

このサンプルフローには、以下で説明する全パターンの実例が含まれています。

📋 サンプルフロー(クリックで展開)

参照元:Node-REDエディター内サンプルフロー

[ { "id": "60e740b9c7fe662f", "type": "tab", "label": "csv", "disabled": false, "info": "", "env": [] }, { "id": "330f4888.cccb28", "type": "inject", "z": "60e740b9c7fe662f", "name": "", "props": [{"p": "payload"}, {"p": "topic", "vt": "str"}], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 270, "y": 160, "wires": [["ed11f8d6.5e3c88"]] }, { "id": "a0288b44.71d488", "type": "csv", "z": "60e740b9c7fe662f", "name": "", "spec": "rfc", "sep": ",", "hdrin": "", "hdrout": "none", "multi": "one", "ret": "\\r\\n", "temp": "", "skip": 0, "strings": true, "include_empty_strings": "", "include_null_values": "", "x": 610, "y": 160, "wires": [["369cbe42.4af9f2"]] }, { "id": "ed11f8d6.5e3c88", "type": "template", "z": "60e740b9c7fe662f", "name": "CSV data", "field": "payload", "fieldType": "msg", "format": "text", "syntax": "mustache", "template": "Apple,100,Canada\nOrange,120,USA\nBanana,80,Philippines", "output": "str", "x": 440, "y": 160, "wires": [["a0288b44.71d488"]] }, { "id": "369cbe42.4af9f2", "type": "debug", "z": "60e740b9c7fe662f", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "statusVal": "", "statusType": "auto", "x": 790, "y": 160, "wires": [] }, { "id": "783cfaa6.52fbe4", "type": "comment", "z": "60e740b9c7fe662f", "name": "Example 1: Parse CSV (default column names, messages)", "info": "", "x": 380, "y": 100, "wires": [] }, { "id": "98c9d44d.4457b8", "type": "inject", "z": "60e740b9c7fe662f", "name": "", "props": [{"p": "payload"}, {"p": "topic", "vt": "str"}], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 270, "y": 360, "wires": [["65476517.3d760c"]] }, { "id": "76df98f7.0dcd08", "type": "csv", "z": "60e740b9c7fe662f", "name": "", "spec": "rfc", "sep": ",", "hdrin": "", "hdrout": "none", "multi": "mult", "ret": "\\r\\n", "temp": "", "skip": 0, "strings": true, "include_empty_strings": "", "include_null_values": "", "x": 610, "y": 360, "wires": [["557979e0.e6b588"]] }, { "id": "65476517.3d760c", "type": "template", "z": "60e740b9c7fe662f", "name": "CSV data", "field": "payload", "fieldType": "msg", "format": "text", "syntax": "mustache", "template": "Apple,100,Canada\nOrange,120,USA\nBanana,80,Philippines", "output": "str", "x": 440, "y": 360, "wires": [["76df98f7.0dcd08"]] }, { "id": "557979e0.e6b588", "type": "debug", "z": "60e740b9c7fe662f", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "statusVal": "", "statusType": "auto", "x": 790, "y": 360, "wires": [] }, { "id": "187f4ab3.4c9ab5", "type": "comment", "z": "60e740b9c7fe662f", "name": "Example 2: Parse CSV (default column names, array)", "info": "", "x": 360, "y": 300, "wires": [] }, { "id": "1216e95b.1b1e87", "type": "inject", "z": "60e740b9c7fe662f", "name": "", "props": [{"p": "payload"}, {"p": "topic", "vt": "str"}], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 280, "y": 540, "wires": [["e41ffbbc.de2ed8"]] }, { "id": "286828bc.9233c8", "type": "csv", "z": "60e740b9c7fe662f", "name": "", "spec": "rfc", "sep": ",", "hdrin": "", "hdrout": "none", "multi": "one", "ret": "\\r\\n", "temp": "kind,price,origin", "skip": 0, "strings": true, "include_empty_strings": "", "include_null_values": "", "x": 620, "y": 540, "wires": [["9d8218c.5550ee8"]] }, { "id": "e41ffbbc.de2ed8", "type": "template", "z": "60e740b9c7fe662f", "name": "CSV data", "field": "payload", "fieldType": "msg", "format": "text", "syntax": "mustache", "template": "Apple,100,Canada\nOrange,120,USA\nBanana,80,Philippines", "output": "str", "x": 450, "y": 540, "wires": [["286828bc.9233c8"]] }, { "id": "9d8218c.5550ee8", "type": "debug", "z": "60e740b9c7fe662f", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "statusVal": "", "statusType": "auto", "x": 800, "y": 540, "wires": [] }, { "id": "aaa1ee8f.21e2c", "type": "comment", "z": "60e740b9c7fe662f", "name": "Example 3: Parse CSV (specified column names)", "info": "", "x": 350, "y": 480, "wires": [] }, { "id": "24093558.0315aa", "type": "inject", "z": "60e740b9c7fe662f", "name": "", "props": [{"p": "payload"}, {"p": "topic", "vt": "str"}], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 280, "y": 720, "wires": [["80abaee1.5fa7f"]] }, { "id": "d4d2ca3f.1d9488", "type": "csv", "z": "60e740b9c7fe662f", "name": "", "spec": "rfc", "sep": ",", "hdrin": true, "hdrout": "none", "multi": "one", "ret": "\\r\\n", "temp": "", "skip": 0, "strings": true, "include_empty_strings": "", "include_null_values": "", "x": 620, "y": 720, "wires": [["b52791c3.08967"]] }, { "id": "80abaee1.5fa7f", "type": "template", "z": "60e740b9c7fe662f", "name": "CSV data", "field": "payload", "fieldType": "msg", "format": "text", "syntax": "mustache", "template": "kind,price,origin\nApple,100,Canada\nOrange,120,USA\nBanana,80,Philippines", "output": "str", "x": 450, "y": 720, "wires": [["d4d2ca3f.1d9488"]] }, { "id": "b52791c3.08967", "type": "debug", "z": "60e740b9c7fe662f", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "statusVal": "", "statusType": "auto", "x": 800, "y": 720, "wires": [] }, { "id": "85091361.85644", "type": "comment", "z": "60e740b9c7fe662f", "name": "Example 4: Parse CSV (first row as column names)", "info": "", "x": 360, "y": 660, "wires": [] }, { "id": "8ca41fee.3303d", "type": "inject", "z": "60e740b9c7fe662f", "name": "", "props": [{"p": "payload"}, {"p": "topic", "vt": "str"}], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 290, "y": 900, "wires": [["c466905b.e8c61"]] }, { "id": "65146d20.d78204", "type": "csv", "z": "60e740b9c7fe662f", "name": "", "spec": "rfc", "sep": ",", "hdrin": false, "hdrout": "none", "multi": "one", "ret": "\\r\\n", "temp": "kind,price", "skip": 0, "strings": true, "include_empty_strings": "", "include_null_values": "", "x": 630, "y": 900, "wires": [["92e99e67.a37d8"]] }, { "id": "c466905b.e8c61", "type": "template", "z": "60e740b9c7fe662f", "name": "JS object", "field": "payload", "fieldType": "msg", "format": "json", "syntax": "plain", "template": "{\n \"kind\": \"Apple\",\n \"price\": 100,\n \"origin\": \"Canada\"\n}", "output": "json", "x": 460, "y": 900, "wires": [["65146d20.d78204"]] }, { "id": "92e99e67.a37d8", "type": "debug", "z": "60e740b9c7fe662f", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "statusVal": "", "statusType": "auto", "x": 810, "y": 900, "wires": [] }, { "id": "9e93169c.b763a8", "type": "comment", "z": "60e740b9c7fe662f", "name": "Example 5: Convert object to CSV", "info": "", "x": 310, "y": 840, "wires": [] }, { "id": "bd0d82ed.7b28", "type": "inject", "z": "60e740b9c7fe662f", "name": "", "props": [{"p": "payload"}, {"p": "topic", "vt": "str"}], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 280, "y": 1060, "wires": [["1d857b8d.3a4014"]] }, { "id": "66a37667.16ebd8", "type": "csv", "z": "60e740b9c7fe662f", "name": "", "spec": "rfc", "sep": ",", "hdrin": false, "hdrout": "none", "multi": "one", "ret": "\\r\\n", "temp": "kind,price", "skip": 0, "strings": true, "include_empty_strings": "", "include_null_values": "", "x": 620, "y": 1060, "wires": [["859725fd.dc93d8"]] }, { "id": "1d857b8d.3a4014", "type": "template", "z": "60e740b9c7fe662f", "name": "JS array", "field": "payload", "fieldType": "msg", "format": "json", "syntax": "plain", "template": "[\n {\"kind\": \"Apple\", \"price\": 100, \"origin\": \"Canada\"},\n {\"kind\": \"Orange\", \"price\": 120, \"origin\": \"USA\"},\n {\"kind\": \"Banana\", \"price\": 80, \"origin\": \"Philippines\"}\n]", "output": "json", "x": 450, "y": 1060, "wires": [["66a37667.16ebd8"]] }, { "id": "859725fd.dc93d8", "type": "debug", "z": "60e740b9c7fe662f", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "statusVal": "", "statusType": "auto", "x": 800, "y": 1060, "wires": [] }, { "id": "e89019c5.70ae78", "type": "comment", "z": "60e740b9c7fe662f", "name": "Example 6: Convert array to CSV", "info": "", "x": 310, "y": 1000, "wires": [] }, { "id": "2b4d538d.ada07c", "type": "inject", "z": "60e740b9c7fe662f", "name": "", "props": [{"p": "payload"}, {"p": "topic", "vt": "str"}], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 280, "y": 1220, "wires": [["3e5c9e8.5065b62"]] }, { "id": "db02c7be.0984e8", "type": "csv", "z": "60e740b9c7fe662f", "name": "", "spec": "rfc", "sep": ",", "hdrin": false, "hdrout": "all", "multi": "one", "ret": "\\r\\n", "temp": "kind,price", "skip": 0, "strings": true, "include_empty_strings": "", "include_null_values": "", "x": 620, "y": 1220, "wires": [["61f8b772.ddb1f8"]] }, { "id": "3e5c9e8.5065b62", "type": "template", "z": "60e740b9c7fe662f", "name": "JS array", "field": "payload", "fieldType": "msg", "format": "json", "syntax": "plain", "template": "[\n {\"kind\": \"Apple\", \"price\": 100, \"origin\": \"Canada\"},\n {\"kind\": \"Orange\", \"price\": 120, \"origin\": \"USA\"},\n {\"kind\": \"Banana\", \"price\": 80, \"origin\": \"Philippines\"}\n]", "output": "json", "x": 450, "y": 1220, "wires": [["db02c7be.0984e8"]] }, { "id": "61f8b772.ddb1f8", "type": "debug", "z": "60e740b9c7fe662f", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "statusVal": "", "statusType": "auto", "x": 800, "y": 1220, "wires": [] }, { "id": "2ebdd51e.c5d17a", "type": "comment", "z": "60e740b9c7fe662f", "name": "Example 7: Convert array to CSV with header", "info": "", "x": 350, "y": 1160, "wires": [] } ]

パターン1: CSVパース(デフォルトカラム名、1行ずつ出力)

用途: CSVをオブジェクトに変換し、1行ずつメッセージとして送信

Inject Template
(CSV)
CSV
(1行ずつ)
→→→ Debug

📌 動作の流れ:

  1. CSVテキスト "Apple,100,Canada\nOrange,120,USA\nBanana,80,Philippines" を入力
  2. CSVノードがカンマと改行で分割
  3. 3つのメッセージが順番に出力される(msg.parts付き)
  4. カラム名はcol1, col2, col3がデフォルト

設定例:

区切り文字: , カラム名: (空白 = col1, col2, col3...を自動生成) 1行目をカラム名に: OFF 出力形式: 1行毎にメッセージを送信 入力: "Apple,100,Canada\nOrange,120,USA\nBanana,80,Philippines" 出力1: {col1: "Apple", col2: "100", col3: "Canada"} 出力2: {col1: "Orange", col2: "120", col3: "USA"} 出力3: {col1: "Banana", col2: "80", col3: "Philippines"}

パターン2: CSVパース(配列で一括出力)

用途: CSVをオブジェクト配列として1つのメッセージで取得

Inject Template
(CSV)
CSV
(配列)
Debug

設定例:

区切り文字: , 出力形式: 単一の配列メッセージとして出力 入力: "Apple,100,Canada\nOrange,120,USA\nBanana,80,Philippines" 出力: [ {col1: "Apple", col2: "100", col3: "Canada"}, {col1: "Orange", col2: "120", col3: "USA"}, {col1: "Banana", col2: "80", col3: "Philippines"} ]

パターン3: CSVパース(カラム名指定)

用途: 意味のあるプロパティ名でオブジェクトを作成

Inject Template
(CSV)
CSV
(kind,price,origin)
Debug

📌 ポイント:

設定例:

区切り文字: , カラム名: kind,price,origin 1行目をカラム名に: OFF 入力: "Apple,100,Canada\nOrange,120,USA" 出力1: {kind: "Apple", price: "100", origin: "Canada"} 出力2: {kind: "Orange", price: "120", origin: "USA"}

パターン4: CSVパース(先頭行をカラム名として使用)

用途: ヘッダー行を含むCSVファイルを処理

Inject Template
(ヘッダー付CSV)
CSV
(1行目=カラム名)
Debug

設定例:

区切り文字: , 1行目をカラム名に: ON 入力: "kind,price,origin\nApple,100,Canada\nOrange,120,USA" 出力1: {kind: "Apple", price: "100", origin: "Canada"} ← 先頭行はスキップ 出力2: {kind: "Orange", price: "120", origin: "USA"}

パターン5: オブジェクトからCSV生成

用途: JavaScriptオブジェクトをCSV文字列に変換

Inject Template
(オブジェクト)
CSV
(kind,price)
Debug

📌 ポイント:

設定例:

カラム名: kind,price ← originは除外 ヘッダー行: なし 入力: {kind: "Apple", price: 100, origin: "Canada"} 出力: "Apple,100\n"

パターン6: 配列からCSV生成(ヘッダー付き)

用途: 配列データをヘッダー行付きのCSVに変換

Inject Template
(配列)
CSV
(ヘッダー:常に)
Debug

設定例:

カラム名: kind,price ヘッダー行: 常に出力 入力: [ {kind: "Apple", price: 100}, {kind: "Orange", price: 120} ] 出力: "kind,price\nApple,100\nOrange,120\n"

🏋️ 4. 実践演習

演習1: 基本的なCSVパース初級

📝 課題:

商品リストのCSVをパースして、商品名と価格を持つオブジェクトに変換してください。

🎯 要求仕様:

📊 期待される動作:

✅ 成功の条件:

💡 ヒント

Injectノードの設定:

  • payload: タイムスタンプ(デフォルト)でOK

Templateノードの設定:

  • テンプレート: りんご,150(改行)みかん,100(改行)バナナ,80
  • 出力形式: 文字列

CSVノードの設定:

  • 区切り文字: ,
  • カラム: name,price
  • 出力: 1行毎にメッセージを送信
✅ 解答例フロー
[ { "id": "ex1_inject", "type": "inject", "name": "実行", "props": [{"p": "payload"}], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 110, "y": 100, "wires": [["ex1_template"]] }, { "id": "ex1_template", "type": "template", "name": "商品CSV", "field": "payload", "fieldType": "msg", "format": "text", "syntax": "plain", "template": "りんご,150\nみかん,100\nバナナ,80", "output": "str", "x": 260, "y": 100, "wires": [["ex1_csv"]] }, { "id": "ex1_csv", "type": "csv", "name": "CSVパース", "spec": "rfc", "sep": ",", "hdrin": "", "hdrout": "none", "multi": "one", "ret": "\\r\\n", "temp": "name,price", "skip": 0, "strings": true, "include_empty_strings": "", "include_null_values": "", "x": 420, "y": 100, "wires": [["ex1_debug"]] }, { "id": "ex1_debug", "type": "debug", "name": "結果", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "x": 570, "y": 100, "wires": [] } ]

演習2: ヘッダー付きCSVのパース中級

📝 課題:

ヘッダー行を含むCSVをパースし、配列として一括取得してください。

🎯 要求仕様:

📊 期待される動作:

✅ 成功の条件:

💡 ヒント

Templateノードの設定:

  • テンプレートの1行目がヘッダー(id,name,score)
  • 2行目以降がデータ

CSVノードの設定:

  • 区切り文字: ,
  • 1行目をカラム名に: チェックON
  • 出力: 単一の配列メッセージとして出力
✅ 解答例フロー
[ { "id": "ex2_inject", "type": "inject", "name": "実行", "props": [{"p": "payload"}], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 110, "y": 100, "wires": [["ex2_template"]] }, { "id": "ex2_template", "type": "template", "name": "成績CSV", "field": "payload", "fieldType": "msg", "format": "text", "syntax": "plain", "template": "id,name,score\n1,田中,85\n2,鈴木,92\n3,佐藤,78", "output": "str", "x": 260, "y": 100, "wires": [["ex2_csv"]] }, { "id": "ex2_csv", "type": "csv", "name": "CSVパース", "spec": "rfc", "sep": ",", "hdrin": true, "hdrout": "none", "multi": "mult", "ret": "\\r\\n", "temp": "", "skip": 0, "strings": true, "include_empty_strings": "", "include_null_values": "", "x": 420, "y": 100, "wires": [["ex2_debug"]] }, { "id": "ex2_debug", "type": "debug", "name": "結果", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "x": 570, "y": 100, "wires": [] } ]

演習3: オブジェクト配列からCSV生成中級

📝 課題:

センサーデータのオブジェクト配列をヘッダー付きCSVに変換してください。

🎯 要求仕様:

📊 期待される動作:

✅ 成功の条件:

💡 ヒント

Templateノードの設定:

  • 形式: JSON
  • 出力: JSONオブジェクト
  • テンプレート: センサーデータの配列

CSVノードの設定:

  • カラム: sensor,temp(humidityを除外)
  • ヘッダー行を出力: 常に出力
✅ 解答例フロー
[ { "id": "ex3_inject", "type": "inject", "name": "実行", "props": [{"p": "payload"}], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 110, "y": 100, "wires": [["ex3_template"]] }, { "id": "ex3_template", "type": "template", "name": "センサーデータ", "field": "payload", "fieldType": "msg", "format": "json", "syntax": "plain", "template": "[\n {\"sensor\": \"A\", \"temp\": 25.5, \"humidity\": 60},\n {\"sensor\": \"B\", \"temp\": 24.2, \"humidity\": 55}\n]", "output": "json", "x": 280, "y": 100, "wires": [["ex3_csv"]] }, { "id": "ex3_csv", "type": "csv", "name": "CSV生成", "spec": "rfc", "sep": ",", "hdrin": false, "hdrout": "all", "multi": "one", "ret": "\\r\\n", "temp": "sensor,temp", "skip": 0, "strings": true, "include_empty_strings": "", "include_null_values": "", "x": 450, "y": 100, "wires": [["ex3_debug"]] }, { "id": "ex3_debug", "type": "debug", "name": "結果", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "x": 590, "y": 100, "wires": [] } ]

演習4: CSV処理パイプライン上級

📝 課題:

CSVをパースし、Joinノードで結合後、別の形式のCSVに再変換してください。

🎯 要求仕様:

📊 期待される動作:

✅ 成功の条件:

💡 ヒント

フローの構成:

  1. Template: ヘッダー付きCSVを作成
  2. CSV(パース): 1行目をカラム名として使用、1行ずつ出力
  3. Join: 自動モードで配列に結合
  4. CSV(生成): kind,priceカラムのみでCSV生成

CSVノード(パース)の設定:

  • 1行目をカラム名に: チェックON
  • 出力: 1行毎にメッセージを送信(msg.parts付き)

Joinノードの設定:

  • モード: 自動

CSVノード(生成)の設定:

  • カラム: kind,price
✅ 解答例フロー
[ { "id": "ex4_inject", "type": "inject", "name": "実行", "props": [{"p": "payload"}], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 110, "y": 100, "wires": [["ex4_template"]] }, { "id": "ex4_template", "type": "template", "name": "元CSV", "field": "payload", "fieldType": "msg", "format": "text", "syntax": "plain", "template": "kind,price,origin\nApple,100,Canada\nOrange,120,USA\nBanana,80,Philippines", "output": "str", "x": 250, "y": 100, "wires": [["ex4_csv_parse"]] }, { "id": "ex4_csv_parse", "type": "csv", "name": "CSVパース", "spec": "rfc", "sep": ",", "hdrin": true, "hdrout": "none", "multi": "one", "ret": "\\r\\n", "temp": "", "skip": 0, "strings": true, "include_empty_strings": "", "include_null_values": "", "x": 400, "y": 100, "wires": [["ex4_join"]] }, { "id": "ex4_join", "type": "join", "name": "配列に結合", "mode": "auto", "build": "array", "property": "payload", "propertyType": "msg", "key": "topic", "joiner": "\\n", "joinerType": "str", "accumulate": false, "timeout": "", "count": "", "reduceRight": false, "x": 560, "y": 100, "wires": [["ex4_csv_gen"]] }, { "id": "ex4_csv_gen", "type": "csv", "name": "CSV生成", "spec": "rfc", "sep": ",", "hdrin": false, "hdrout": "all", "multi": "one", "ret": "\\r\\n", "temp": "kind,price", "skip": 0, "strings": true, "include_empty_strings": "", "include_null_values": "", "x": 710, "y": 100, "wires": [["ex4_debug"]] }, { "id": "ex4_debug", "type": "debug", "name": "結果", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "x": 850, "y": 100, "wires": [] } ]

🎓 5. まとめ

CSVノードの重要ポイント

⚠️ よくある間違い

📚 次のステップ

CSVノードをマスターしたら、以下のノードも学んでみましょう:

🔧 6. トラブルシューティング

よくある問題と解決方法

問題 原因 解決方法
数値が文字列になる 数値変換がOFF 「数値を変換」オプションをONに
カラム名がcol1,col2... カラム名未指定 カラム設定または1行目をカラム名として使用
出力プロパティが不足 カラム名でフィルタリング 必要なプロパティをすべてカラムに指定
文字化け 文字コードの不一致 UTF-8で統一、BOM付きの場合は除去
行が結合される 改行コードの違い 区切り文字設定を確認(\n or \r\n)
引用符が残る CSVの引用符処理 標準的なCSV形式に修正

💡 7. 実務での活用例

ケース1: センサーデータのログ記録

MQTTノード(センサーデータ受信) ↓ Functionノード(データ整形) ↓ CSVノード(CSV形式に変換) ↓ File Appendノード(ファイルに追記) 用途: IoTセンサーからのデータをCSVファイルに記録

ケース2: 設定ファイルの読み込み

File Inノード(config.csv読み込み) ↓ CSVノード(パース、配列出力) ↓ Changeノード(フロー変数に保存) 用途: 外部CSVファイルから設定値を読み込み

ケース3: レポート生成

HTTPリクエスト or DB照会 ↓ Functionノード(データ集計) ↓ CSVノード(ヘッダー付きCSV生成) ↓ Emailノード or HTTP Responseノード 用途: 日次レポートをCSV形式で生成・送信

ケース4: データ変換パイプライン

File Inノード(外部CSVファイル) ↓ CSVノード(パース) ↓ Switchノード(フィルタリング) ↓ Joinノード(再結合) ↓ CSVノード(新形式で生成) ↓ File Outノード(変換後ファイル出力) 用途: CSVファイルの形式変換、フィルタリング、加工

🔗 8. 追加リソース


このガイドが役に立ちましたら、実際のプロジェクトで練習してみてください!
CSVノードはデータ連携の基本ツールです。

参照元:Node-REDエディター内サンプルフロー

🏠