CSV เป็น JSON ใน JavaScript
ใช้ แปลง CSV เป็น JSON ฟรีโดยตรงในเบราว์เซอร์ของคุณ — ไม่ต้องติดตั้ง
ลอง แปลง CSV เป็น JSON ออนไลน์ →ข้อมูล CSV ส่วนใหญ่ที่พบมักมาในรูปสตริงแบน จากการอัปโหลดไฟล์ การส่งออกจากฐานข้อมูล หรือ API ที่ยังใช้รูปแบบจากยุค 1970 เพื่อ แปลง CSV เป็น JSON ใน JavaScript คุณต้องการสองสิ่งที่ภาษาให้มาฟรี: การแบ่งสตริงเพื่อ parse แถว และ JSON.stringify() เพื่อ serialize ผลลัพธ์ ไม่จำเป็นต้องติดตั้ง npm สำหรับพื้นฐาน — คู่มือนี้ครอบคลุมทั้ง pipeline ตั้งแต่ยูทิลิตี csvToJson() ที่นำกลับมาใช้ได้ ไปจนถึง PapaParse และการทำงานกับไฟล์ใน Node.js สำหรับการแปลงด่วนโดยไม่ต้องเขียนโค้ด เครื่องมือแปลง CSV เป็น JSON ออนไลน์ ทำให้เสร็จทันที ตัวอย่างทั้งหมดรองรับ Node.js 18+ และเบราว์เซอร์สมัยใหม่
- ✓แบ่ง CSV ด้วยขึ้นบรรทัดใหม่ ดึง header จากแถว 0 map แถวที่เหลือเป็นอ็อบเจกต์ จากนั้นใช้ JSON.stringify(array, null, 2) สำหรับผลลัพธ์ที่อ่านง่าย
- ✓JSON.stringify() สร้างสตริง JSON.parse() แปลงกลับเป็นอาร์เรย์ JavaScript ที่มีชีวิต — รู้ว่าคุณมีอะไรก่อนดำเนินการ
- ✓อินสแตนซ์ Map ไม่ serialize เป็น JSON โดยอัตโนมัติ — เรียก Object.fromEntries(map) ก่อน
- ✓สำหรับ CSV ที่มี field มีเครื่องหมายคำพูด คอมม่าภายในค่า หรือขึ้นบรรทัดใหม่ในเซลล์ ใช้ PapaParse หรือ csv-parse แทนการแบ่งแบบง่าย
- ✓csvtojson (npm) จัดการการ coerce ชนิดข้อมูล สตรีมมิง และ edge case ของ RFC 4180 ในการเรียกครั้งเดียว
การแปลง CSV เป็น JSON คืออะไร?
การแปลง CSV เป็น JSON แปลงรูปแบบข้อความที่คั่นด้วยคอมม่าแบบแบนให้เป็นอาร์เรย์ของอ็อบเจกต์ ที่มีโครงสร้าง ซึ่งแต่ละแถวจะกลายเป็นอ็อบเจกต์ JavaScript ที่ใช้ header ของคอลัมน์เป็นคีย์ รูปแบบ CSV ไม่มีชนิดข้อมูล — ทุกอย่างเป็นสตริง JSON เพิ่มโครงสร้าง การซ้อนกัน และชนิดข้อมูลที่ชัดเจน (ตัวเลข บูลีน null) การแปลงนี้เป็นขั้นตอนแรกใน pipeline ข้อมูลเกือบทุกรายการที่เริ่มต้นจากการส่งออกสเปรดชีต การ dump จากระบบเก่า หรือ ไฟล์ที่ผู้ใช้อัปโหลด ข้อมูลพื้นฐานเหมือนเดิม รูปแบบเปลี่ยนจากคอลัมน์ที่ใช้ตำแหน่ง เป็น property ที่มีชื่อ
name,email,role,active สมชาย ใจดี,somchai@nexuslabs.io,Engineering Lead,true นภา วงศ์สุข,napa@nexuslabs.io,Product Manager,true
[
{
"name": "สมชาย ใจดี",
"email": "somchai@nexuslabs.io",
"role": "Engineering Lead",
"active": "true"
},
{
"name": "นภา วงศ์สุข",
"email": "napa@nexuslabs.io",
"role": "Product Manager",
"active": "true"
}
]csvToJson() — สร้างฟังก์ชันแปลงที่นำกลับมาใช้ได้
pipeline การแปลง CSV เป็น JSON ใน JavaScript แบ่งออกเป็นสามขั้นตอน: แบ่งสตริง CSV ด้วยขึ้นบรรทัดใหม่เพื่อรับแถว ดึง header จากแถวแรกด้วย split(','), จากนั้น map แต่ละแถวที่เหลือเป็นอ็อบเจกต์ JavaScript ธรรมดาที่มี key จาก header และ value จากตำแหน่งคอลัมน์ที่ตรงกัน การเรียก JSON.stringify() สุดท้ายแปลงอาร์เรย์ของอ็อบเจกต์นั้นเป็นสตริง JSON นี่คือเวอร์ชันที่ทำงานได้น้อยที่สุด:
function csvToJson(csv) {
const lines = csv.trim().split('\n')
const headers = lines[0].split(',').map(h => h.trim())
const rows = lines.slice(1)
.filter(line => line.trim() !== '')
.map(line => {
const values = line.split(',')
return Object.fromEntries(
headers.map((header, i) => [header, values[i]?.trim()])
)
})
return JSON.stringify(rows, null, 2)
}
const csv = `server,port,region,status
api-gateway,8080,us-east-1,healthy
auth-service,8443,eu-west-1,degraded
payments-api,9090,ap-south-1,healthy`
console.log(csvToJson(csv))
// [
// { "server": "api-gateway", "port": "8080", "region": "us-east-1", "status": "healthy" },
// { "server": "auth-service", "port": "8443", "region": "eu-west-1", "status": "degraded" },
// { "server": "payments-api", "port": "9090", "region": "ap-south-1", "status": "healthy" }
// ]ฟังก์ชันนั้นจัดการพื้นฐาน: ขึ้นบรรทัดใหม่ท้ายสตริง บรรทัดว่าง ช่องว่างรอบค่า ทุก field ของ CSV จะผ่านมาเป็นสตริง สังเกตว่า port คือ "8080" (สตริง) ไม่ใช่ 8080 (ตัวเลข) หากต้องการชนิดข้อมูลที่ถูกต้องในผลลัพธ์ JSON คุณต้อง coerce เอง นี่คือเวอร์ชันขยายพร้อมการตรวจจับชนิดข้อมูล:
function coerceValue(val) {
if (val === undefined || val === '') return null
if (val === 'true') return true
if (val === 'false') return false
if (val === 'null') return null
const num = Number(val)
if (!isNaN(num) && val.trim() !== '') return num
return val
}
function csvToJson(csv, { coerce = false } = {}) {
const lines = csv.trim().split('\n')
const headers = lines[0].split(',').map(h => h.trim())
const rows = lines.slice(1)
.filter(line => line.trim() !== '')
.map(line => {
const values = line.split(',')
return Object.fromEntries(
headers.map((header, i) => [
header,
coerce ? coerceValue(values[i]?.trim()) : values[i]?.trim()
])
)
})
return JSON.stringify(rows, null, 2)
}
const csv = `endpoint,port,max_connections,debug
/api/v2/orders,8443,500,true
/api/v2/health,8080,100,false`
console.log(csvToJson(csv, { coerce: true }))
// [
// { "endpoint": "/api/v2/orders", "port": 8443, "max_connections": 500, "debug": true },
// { "endpoint": "/api/v2/health", "port": 8080, "max_connections": 100, "debug": false }
// ]flag coerce เป็นแบบ opt-in เพราะการตรวจจับชนิดข้อมูลอัตโนมัติอาจให้ผลไม่ดี — field เช่นรหัสไปรษณีย์ ("07302") จะสูญเสียเลขศูนย์นำหน้าเมื่อแปลงเป็นตัวเลข เปิดใช้ coercion เฉพาะเมื่อคุณควบคุม schema หมายเหตุเพิ่มเติม: JSON.stringify() รับอาร์กิวเมนต์ที่สาม space สำหรับการย่อหน้า ส่ง 2 สำหรับสองช่อง 4 สำหรับสี่ช่อง หรือ "\t" สำหรับ tab ละเว้นเพื่อผลลัพธ์แบบกระชับในบรรทัดเดียว — มีประโยชน์เมื่อส่ง สตริง JSON เป็น body ของ API request ที่ช่องว่างเป็นแค่ bandwidth ที่เสียเปล่า
JSON.parse() โดยตรงบนข้อความ CSV จะเกิด SyntaxError คุณต้องแปลง CSV เป็นอ็อบเจกต์ JavaScript ก่อน ด้วยฟังก์ชัน csvToJson() ซึ่งภายในเรียก JSON.stringify() เพื่อสร้างสตริง JSON จริงๆการจัดการ Map, Date และอ็อบเจกต์กำหนดเองจากข้อมูล CSV
การแปลง CSV ไม่ได้จบลงเสมอด้วยอาร์เรย์แบนของอ็อบเจกต์ธรรมดา บางครั้งคุณต้องสร้าง Map จากคู่ header-value parse สตริงวันที่เป็นอ็อบเจกต์ Date หรือเพิ่ม property ที่คำนวณ ก่อน serialize JavaScript มีข้อที่ทำให้สับสน: อินสแตนซ์ Map ไม่ serialize ด้วย JSON.stringify()คุณจะได้อ็อบเจกต์ว่าง วิธีแก้คือ Object.fromEntries() เพื่อแปลง Map กลับเป็นอ็อบเจกต์ธรรมดาก่อน stringify
สาเหตุที่ Map serialize เป็น {} คือ JSON.stringify() วนซ้ำ property ของอ็อบเจกต์ที่ enumerable ได้ Map เก็บ entry ไว้ใน internal slot ไม่ใช่เป็น property ที่ enumerable บนอ็อบเจกต์เอง ดังนั้น serializer จึงเห็นอ็อบเจกต์ที่ไม่มี key prototype ของ Map ยังขาดเมธอด toJSON() ซึ่งเป็น hook ที่ JSON.stringify() เรียกก่อนสำหรับค่าใดๆ ก่อนตัดสินใจว่าจะ serialize อย่างไร หากค่ามี toJSON(), ค่าที่คืนจากเมธอดนั้นจะถูก serialize — ไม่ใช่อ็อบเจกต์เอง นี่คือเหตุที่อ็อบเจกต์ Date serialize ได้ถูกต้อง: Date.prototype.toJSON คืนสตริง ISO 8601 ดังนั้น JSON.stringify(new Date()) สร้าง timestamp ที่มีเครื่องหมายคำพูดแทนอ็อบเจกต์ว่าง การเข้าใจ hook นี้ให้คุณกำหนดพฤติกรรมเดียวกัน บนคลาสของคุณเอง — ดังที่แสดงในตัวอย่าง EmployeeRecord ด้านล่าง — เพื่อควบคุมว่า field ที่ได้จาก CSV ใดจะปรากฏในผลลัพธ์ JSON สุดท้าย
แปลง Map เป็น JSON
// สร้าง Map จากคู่ header→value ของ CSV
const headers = ['server', 'port', 'region']
const values = ['payments-api', '9090', 'ap-south-1']
const rowMap = new Map(headers.map((h, i) => [h, values[i]]))
// Map ไม่ serialize โดยตรง
console.log(JSON.stringify(rowMap))
// "{}" — อ็อบเจกต์ว่าง ข้อมูลหาย!
// แปลงเป็นอ็อบเจกต์ธรรมดาก่อน
const rowObj = Object.fromEntries(rowMap)
console.log(JSON.stringify(rowObj, null, 2))
// {
// "server": "payments-api",
// "port": "9090",
// "region": "ap-south-1"
// }สตริงวันที่และ toJSON()
field วันที่ใน CSV มาเป็นสตริง หากคุณ parse เป็นอ็อบเจกต์ Date ระหว่างการประมวลผล Date เหล่านั้นจะ serialize ถูกต้องเพราะ Date มีเมธอด toJSON() ที่ built-in ซึ่งคืนสตริง ISO 8601 คุณยังสามารถกำหนด toJSON() เองบนคลาสของคุณเพื่อควบคุมว่าคอลัมน์ CSV ใดจะปรากฏในผลลัพธ์ที่ serialize — ตัวอย่างเช่น การละ field ติดตามภายในเช่น _rowIndex
class EmployeeRecord {
constructor(csvRow) {
this._rowIndex = csvRow._rowIndex // ภายใน ไม่ใช่สำหรับ JSON
this.employeeId = csvRow.employee_id
this.name = csvRow.name
this.hiredAt = new Date(csvRow.hired_date)
this.salary = Number(csvRow.salary)
}
toJSON() {
// แสดงเฉพาะ field ที่ต้องการในผลลัพธ์ JSON
return {
employee_id: this.employeeId,
name: this.name,
hired_at: this.hiredAt, // Date.toJSON() → ISO string อัตโนมัติ
salary: this.salary,
}
}
}
const csvRow = {
_rowIndex: 42,
employee_id: 'EMP-2847',
name: 'สมชาย ใจดี',
hired_date: '2024-03-15',
salary: '128000',
}
const record = new EmployeeRecord(csvRow)
console.log(JSON.stringify(record, null, 2))
// {
// "employee_id": "EMP-2847",
// "name": "สมชาย ใจดี",
// "hired_at": "2024-03-15T00:00:00.000Z",
// "salary": 128000
// }
// หมายเหตุ: _rowIndex ถูกยกเว้น salary เป็นตัวเลข วันที่อยู่ในรูปแบบ ISOReviver สำหรับการ Deserialize วันที่
หลังจากเขียน JSON ที่ได้จาก CSV ลงไฟล์หรือส่งผ่านเครือข่าย JSON.parse() จะคืนอ็อบเจกต์ธรรมดา — อ็อบเจกต์ Date จะกลายเป็นสตริงอีกครั้ง ใช้ฟังก์ชัน reviver เพื่อแปลงสตริง ISO 8601 กลับเป็นอ็อบเจกต์ Date ระหว่างการ parse:
const jsonString = '{"employee_id":"EMP-2847","name":"สมชาย ใจดี","hired_at":"2024-03-15T00:00:00.000Z","salary":128000}'
const isoDatePattern = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/
const parsed = JSON.parse(jsonString, (key, value) => {
if (typeof value === 'string' && isoDatePattern.test(value)) {
return new Date(value)
}
return value
})
console.log(parsed.hired_at instanceof Date) // true
console.log(parsed.hired_at.getFullYear()) // 2024JSON.stringify() คืน undefined (ไม่ใช่สตริง) สำหรับค่าที่มี function, Symbol หรือ property ที่เป็น undefined หากอ็อบเจกต์ที่ได้จาก CSV บังเอิญรับค่า undefined จากคอลัมน์ที่หายไป property นั้น จะหายออกจากผลลัพธ์ JSON โดยไม่มีการเตือน ควร default ค่าที่หายไปเป็น null เสมอเอกสารอ้างอิงพารามิเตอร์ JSON.stringify()
รูปแบบฟังก์ชันคือ JSON.stringify(value, replacer?, space?)อาร์กิวเมนต์ replacer และ space เป็น optional ทั้งคู่ — ส่ง null สำหรับ replacer เมื่อต้องการเฉพาะการย่อหน้า
พารามิเตอร์ของ JSON.parse():
JSON.parse() — การนำผลลัพธ์ JSON ไปใช้
เมื่อได้สตริง JSON จาก csvToJson(), ขั้นตอนถัดไปมักเป็นการ parse กลับเป็นอาร์เรย์ JavaScript ที่มีชีวิตสำหรับการกรอง การ mapping หรือการส่งไปยัง API ความแตกต่างระหว่างสตริง JSON (typeof === "string") และอ็อบเจกต์ JavaScript มีความสำคัญ คุณไม่สามารถเรียก .filter() หรือเข้าถึง [0].name บนสตริง — คุณต้องใช้ JSON.parse() ก่อน การทำงานแบบวงจร (stringify แล้ว parse) ยังทำงานเป็นเทคนิคตรวจสอบได้: หากการแปลง CSV สร้างสิ่งที่ไม่ใช่ JSON ที่ถูกต้อง parse จะ throw อาร์กิวเมนต์ optional ที่เรียกว่า reviver ให้คุณแปลงแต่ละคู่ key-value ระหว่างการ parse — มีประโยชน์ สำหรับการคืนอ็อบเจกต์ Date จากสตริง ISO หรือการเปลี่ยนชื่อ key โดยไม่ต้องผ่านครั้งแยก
const csv = `endpoint,method,avg_latency_ms,error_rate
/api/v2/orders,POST,342,0.02
/api/v2/health,GET,12,0.00
/api/v2/payments,POST,890,0.15
/api/v2/users,GET,45,0.01`
// ขั้นตอนที่ 1: แปลง CSV เป็นสตริง JSON
const jsonString = csvToJson(csv, { coerce: true })
// ขั้นตอนที่ 2: parse กลับเป็นอาร์เรย์ JavaScript
const endpoints = JSON.parse(jsonString)
// ตรวจสอบว่าเป็นอาร์เรย์
console.log(Array.isArray(endpoints)) // true
// กรอง endpoint ที่มี latency สูง
const slow = endpoints.filter(ep => ep.avg_latency_ms > 200)
console.log(slow.map(ep => ep.endpoint))
// ["/api/v2/orders", "/api/v2/payments"]
// Destructure แถวแรก
const [first, ...rest] = endpoints
console.log(first.endpoint) // "/api/v2/orders"
console.log(rest.length) // 3wrapper ที่ปลอดภัยสำหรับ JSON.parse() มีประโยชน์เมื่อตรวจสอบผลลัพธ์การแปลงก่อนการประมวลผลต่อเนื่อง หากการแปลง CSV สร้าง JSON ที่ผิดรูปแบบด้วยเหตุใดก็ตาม (input ที่ถูกตัด ข้อผิดพลาดด้านการเข้ารหัส) วิธีนี้จะรับไว้โดยไม่ crash:
function safeParse(jsonString) {
try {
return { data: JSON.parse(jsonString), error: null }
} catch (err) {
return { data: null, error: err.message }
}
}
// ผลลัพธ์ที่ถูกต้อง
const result = safeParse(csvToJson(csv))
if (result.error) {
console.error('การแปลง CSV สร้าง JSON ที่ไม่ถูกต้อง:', result.error)
} else {
console.log(`Parse แล้ว ${result.data.length} แถว`)
}
// ส่ง CSV ดิบไปยัง JSON.parse โดยไม่ได้ตั้งใจ — นี่จะล้มเหลว
const bad = safeParse('name,email\nสมชาย,somchai@nexuslabs.io')
console.log(bad.error) // "Unexpected token 'a', "name,email"... is not valid JSON"Reviver สำหรับการเปลี่ยนชื่อ Key และการตรวจสอบ
ฟังก์ชัน reviver รับทุกคู่ key-value ระหว่างการ parse จาก property ที่อยู่ในสุดออกมา การคืน undefined สำหรับ key จะลบมันออกจากผลลัพธ์ทั้งหมด การคืนค่าที่ต่างออกไปจะแทนที่มัน reviver มีประโยชน์สำหรับการเปลี่ยนชื่อ header (camelCase เป็น snake_case) การลบ field ภายใน หรือการตรวจสอบว่าคอลัมน์ที่จำเป็นมีอยู่ มันถูกเรียกด้วยค่า root สุดท้าย (key สตริงว่าง) ซึ่งเป็นที่ที่คุณ throw หากผลลัพธ์ไม่ใช่อาร์เรย์
const jsonString = csvToJson(`employeeId,firstName,hiredDate
EMP-2847,สมชาย,2024-03-15
EMP-3012,นภา,2023-11-01`, { coerce: false })
const camelToSnake = str => str.replace(/[A-Z]/g, c => '_' + c.toLowerCase())
const employees = JSON.parse(jsonString, function(key, value) {
// ค่า root — ตรวจสอบรูปทรง
if (key === '') {
if (!Array.isArray(value)) throw new Error('Expected JSON array from CSV')
return value
}
// เปลี่ยนชื่อ key camelCase เป็น snake_case
if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
return Object.fromEntries(
Object.entries(value).map(([k, v]) => [camelToSnake(k), v])
)
}
return value
})
console.log(employees[0])
// { employee_id: 'EMP-2847', first_name: 'สมชาย', hired_date: '2024-03-15' }แปลง CSV จากไฟล์และ API Response
สองแหล่งที่ข้อมูล CSV มาจริงใน production: ไฟล์บนดิสก์และ HTTP response ทั้งสองสถานการณ์ต้องการการจัดการข้อผิดพลาดเพราะ input มาจากภายนอกและไม่สามารถควบคุมได้
อ่านไฟล์ CSV แปลง และเขียน JSON
import { readFileSync, writeFileSync } from 'node:fs'
function csvToJsonFromFile(inputPath, outputPath) {
let csvText
try {
csvText = readFileSync(inputPath, 'utf8')
} catch (err) {
throw new Error(`ไม่สามารถอ่าน ${inputPath}: ${err.message}`)
}
const lines = csvText.trim().split('\n')
if (lines.length < 2) {
throw new Error(`${inputPath} ไม่มีแถวข้อมูล (มีเพียง ${lines.length} บรรทัด)`)
}
const headers = lines[0].split(',').map(h => h.trim())
const rows = lines.slice(1)
.filter(line => line.trim() !== '')
.map(line => {
const values = line.split(',')
return Object.fromEntries(headers.map((h, i) => [h, values[i]?.trim()]))
})
const jsonOutput = JSON.stringify(rows, null, 2)
writeFileSync(outputPath, jsonOutput, 'utf8')
console.log(`แปลงแล้ว ${rows.length} แถว → ${outputPath}`)
return rows
}
// การใช้งาน
const data = csvToJsonFromFile('inventory.csv', 'inventory.json')
console.log(data[0])
// { sku: "WDG-2847", warehouse: "us-east-1", quantity: "150", ... }ดึง CSV จาก API Endpoint
async function fetchCsvAsJson(url) {
const response = await fetch(url)
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`)
}
const contentType = response.headers.get('content-type') || ''
if (!contentType.includes('text/csv') && !contentType.includes('text/plain')) {
console.warn(`content-type ไม่คาดคิด: ${contentType}`)
}
const csvText = await response.text()
const lines = csvText.trim().split('\n')
const headers = lines[0].split(',').map(h => h.trim())
const rows = lines.slice(1)
.filter(line => line.trim() !== '')
.map(line => {
const values = line.split(',')
return Object.fromEntries(headers.map((h, i) => [h, values[i]?.trim()]))
})
return rows
}
// ตัวอย่าง: ดึง CSV อัตราแลกเปลี่ยนจากผู้ให้บริการข้อมูล
try {
const rates = await fetchCsvAsJson('https://data.ecb.internal/rates/daily.csv')
console.log(JSON.stringify(rates.slice(0, 3), null, 2))
// ส่งเป็น JSON ไปยัง service ต่อเนื่อง
await fetch('https://api.internal/v2/rates', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ data: rates }),
})
} catch (err) {
console.error('การซิงค์อัตราแลกเปลี่ยนล้มเหลว:', err.message)
}JSON.stringify() ให้คุณ whitelist คอลัมน์เฉพาะ จาก CSV ส่งอาร์เรย์ชื่อ header เพื่อรวมเฉพาะ field เหล่านั้น: JSON.stringify(rows, ['name', 'email', 'department'])Property ที่ไม่อยู่ในอาร์เรย์จะถูกยกเว้นออกจากผลลัพธ์โดยไม่มีการเตือนการแปลง CSV เป็น JSON ผ่าน Command Line
Node.js สามารถรัน inline script ได้ และมีเครื่องมือ CLI เฉพาะที่จัดการการแปลง CSV เป็น JSON โดยไม่ต้องเขียน script
# Pipe CSV ไปยัง inline script ของ Node.js
cat servers.csv | node -e "
const lines = require('fs').readFileSync('/dev/stdin','utf8').trim().split('\n');
const h = lines[0].split(',');
const rows = lines.slice(1).map(l => Object.fromEntries(h.map((k,i) => [k.trim(), l.split(',')[i]?.trim()])));
console.log(JSON.stringify(rows, null, 2));
"# Miller เป็น Swiss Army knife สำหรับข้อมูลที่มีโครงสร้าง # ติดตั้ง: brew install miller (macOS) หรือ apt install miller (Debian/Ubuntu) mlr --icsv --ojson cat inventory.csv # กรองแถวระหว่างการแปลง mlr --icsv --ojson filter '$quantity > 100' inventory.csv # เลือกคอลัมน์เฉพาะ mlr --icsv --ojson cut -f sku,warehouse,quantity inventory.csv
# ติดตั้งแบบ global npm install -g csvtojson # แปลงไฟล์ csvtojson servers.csv > servers.json # Pipe จาก stdin cat exports/q1-metrics.csv | csvtojson > q1-metrics.json
สำหรับไฟล์ขนาดใหญ่ Miller มักเป็นตัวเลือกที่ดีกว่า csvtojson Miller ถูกเขียนด้วย C และประมวลผล CSV เป็น stream โดยไม่โหลดไฟล์ทั้งหมดเข้าหน่วยความจำ ซึ่งหมายความว่าสามารถจัดการกับ export ขนาดหลาย GB ด้วยการใช้หน่วยความจำคงที่ มันยังรองรับการดำเนินการระดับ field ในที่เดียว — การเปลี่ยนชื่อคอลัมน์ การแปลงชนิดข้อมูล การกรองแถว — ก่อนที่ข้อมูลจะกลายเป็น JSON ดังนั้นคุณจึงหลีกเลี่ยง pipeline แบบสองขั้นตอน parse-then-transform ในทางกลับกัน csvtojson ทำงานบน Node.js และสะดวกกว่าเมื่อ toolchain ที่เหลือเป็น JavaScript: คุณสามารถ pipe output ไปยัง Node streams โดยตรง import เป็น library หรือใช้ API colParser สำหรับการ coerce ชนิดข้อมูลต่อคอลัมน์ในโค้ด ใช้ Miller สำหรับ throughput สูงและ shell pipeline ใช้ csvtojson เมื่อต้องการการผสานรวมกับแอปพลิเคชัน Node.js อย่างใกล้ชิด
jq ไม่ parse CSV โดยตรง หากต้องการใช้ jq ใน pipeline ให้แปลงเป็น JSON ก่อนด้วย csvtojson หรือ mlr จากนั้น pipe ผลลัพธ์ JSON ไปยัง jq สำหรับการกรองและแปลงทางเลือกที่มีประสิทธิภาพสูง — PapaParse
วิธีการ split(',') แบบง่ายจะพังกับไฟล์ CSV จากโลกความเป็นจริง field ที่มีเครื่องหมายคำพูดซึ่งมีคอมม่า ขึ้นบรรทัดใหม่ที่ฝังอยู่ เครื่องหมายคำพูดคู่ที่ escape — ทั้งหมดนี้ทำให้การแบ่งแบบง่ายพัง PapaParse คือ library ที่เหมาะสำหรับเมื่อ CSV มาจากแหล่งที่ไม่รู้จัก มันจัดการ edge case ทุกกรณีของ RFC 4180 ตรวจจับตัวคั่นอัตโนมัติ และทำงานได้ทั้งใน Node.js และเบราว์เซอร์
npm install papaparse
import Papa from 'papaparse'
const csv = `product,description,price,in_stock
"Widget, Large","A premium widget with ""extra"" features",29.99,true
Bolt Assembly,Standard M8 bolt kit,4.50,true
"Gasket Set","Includes gasket, seal, and O-ring",12.75,false`
const { data, errors, meta } = Papa.parse(csv, {
header: true,
dynamicTyping: true, // แปลงตัวเลขและบูลีนอัตโนมัติ
skipEmptyLines: true,
transformHeader: h => h.trim().toLowerCase().replace(/\s+/g, '_'),
})
if (errors.length > 0) {
console.error('ข้อผิดพลาดในการ parse:', errors)
}
console.log(JSON.stringify(data, null, 2))
// [
// {
// "product": "Widget, Large",
// "description": "A premium widget with \"extra\" features",
// "price": 29.99,
// "in_stock": true
// },
// ...
// ]
console.log(`Parse แล้ว ${data.length} แถว ตัวคั่น: "${meta.delimiter}"`)ตัวเลือก dynamicTyping ของ PapaParse ทำการ coerce ชนิดข้อมูลอัตโนมัติ — ตัวเลขกลายเป็นตัวเลข "true"/"false" กลายเป็นบูลีน callback transformHeader ทำให้ชื่อคอลัมน์เป็น snake_case มาตรฐาน ซึ่งช่วยให้ไม่ต้องจัดการกับ header ที่ไม่สอดคล้องกัน จาก CSV export ที่ต่างกัน สำหรับการแปลงด่วนโดยไม่ต้องเขียนโค้ด parse ใดๆ เครื่องมือแปลง CSV เป็น JSON จัดการทั้งหมดนี้ในเบราว์เซอร์
Output ใน Terminal พร้อม Syntax Highlighting
การ dump อาร์เรย์ JSON ขนาดใหญ่ลงใน terminal ทำให้สายตาเบลอเร็ว การเพิ่ม syntax highlighting ให้กับ output ทำให้อ่านได้ง่ายขึ้นระหว่างการ debug และการพัฒนา แพ็กเกจ cli-highlight เพิ่มสีให้กับ JSON output ใน Node.js terminal
npm install cli-highlight
import { highlight } from 'cli-highlight'
// หลังจากแปลง CSV เป็นอาร์เรย์ JSON
const jsonOutput = JSON.stringify(rows, null, 2)
// แสดงพร้อม syntax highlighting
console.log(highlight(jsonOutput, { language: 'json' }))
// Key สตริง ตัวเลข และบูลีนแต่ละอย่างได้รับสีที่แตกต่างกันOutput ที่มีสีสันจะคุ้มค่าเมื่อคุณตรวจสอบผลลัพธ์การแปลงขนาดใหญ่แบบ interactive JSON key ค่าสตริง ตัวเลข และบูลีนแต่ละอย่างได้รับสี ANSI ที่แตกต่างกัน ซึ่งทำให้ง่ายต่อการสังเกตว่า field ใดมีชนิดข้อมูลผิด — ตัวอย่างเช่น หมายเลข port ที่ควรเป็น 8080 แต่ถูก highlight เป็นสตริงเพราะ coercion ปิดอยู่ สิ่งนี้มีประโยชน์เป็นพิเศษเมื่อ debug ไฟล์ CSV ที่ส่งออกจากเครื่องมือสเปรดชีตที่ชนิดข้อมูลของคอลัมน์ไม่สอดคล้องกัน ระหว่างแถว หากไม่มีสี การสแกน JSON 50 แถวเพื่อหา field ที่ผิดชนิดข้อมูลเดียว หมายถึงการอ่านทุกค่าทีละตัว เมื่อมีสี ตัวเลขที่ถูก highlight เป็นสตริงจะโดดเด่นทันที
การทำงานกับไฟล์ CSV ขนาดใหญ่
การโหลดไฟล์ CSV ขนาด 500 MB เข้าสตริงด้วย readFileSync() จะกินหน่วยความจำและอาจทำให้ process crash สำหรับไฟล์ขนาดใหญ่ ควร stream CSV ทีละบรรทัดและ emit อ็อบเจกต์ JSON เมื่อมาถึง แพ็กเกจ csv-parse (ส่วนหนึ่งของ csv ecosystem บน npm) มี streaming parser ที่ทำงานกับ Node.js streams
Streaming CSV เป็น NDJSON ด้วย csv-parse
NDJSON (Newline-Delimited JSON) คือรูปแบบที่แต่ละบรรทัดของไฟล์ output เป็นอ็อบเจกต์ JSON ที่ครบสมบูรณ์ในตัวเอง แตกต่างจากอาร์เรย์ JSON ขนาดใหญ่เดียว — ซึ่งต้องการให้ไฟล์ทั้งหมด อยู่ในหน่วยความจำก่อนเริ่มอ่าน — ไฟล์ NDJSON สามารถประมวลผลทีละบรรทัดได้ ทำให้ NDJSON เหมาะสำหรับ dataset ขนาดใหญ่ที่จะถูกใช้โดย log processor stream pipeline หรือฐานข้อมูลที่มี API นำเข้าแบบ bulk แพ็กเกจ csv-parse emit อ็อบเจกต์ JavaScript หนึ่งอันต่อแถว CSV ใน object mode ดังนั้นคุณสามารถ pipe ไปยัง transform stream ที่ต่อท้าย \n หลังแต่ละ JSON.stringify(row)
import { createReadStream, createWriteStream } from 'node:fs'
import { parse } from 'csv-parse'
import { Transform } from 'node:stream'
import { pipeline } from 'node:stream/promises'
// แปลงแต่ละ CSV row object เป็น JSON line
const toNdjson = new Transform({
objectMode: true,
transform(record, encoding, callback) {
callback(null, JSON.stringify(record) + '\n')
},
})
await pipeline(
createReadStream('telemetry-2026-03.csv'),
parse({
columns: true, // ใช้แถวแรกเป็น header
skip_empty_lines: true,
trim: true,
cast: true, // แปลงตัวเลขและบูลีนอัตโนมัติ
}),
toNdjson,
createWriteStream('telemetry-2026-03.ndjson')
)
console.log('การแปลงแบบ streaming เสร็จสมบูรณ์')
// แต่ละบรรทัดในไฟล์ output คืออ็อบเจกต์ JSON หนึ่งอัน:
// {"timestamp":"2026-03-15T08:22:00Z","service":"gateway","latency_ms":42,"status":200}
// {"timestamp":"2026-03-15T08:22:01Z","service":"auth","latency_ms":156,"status":401}
// ...PapaParse Streaming สำหรับเบราว์เซอร์และ Node.js
โหมด streaming ของ PapaParse ใช้ callback step ที่ทำงานครั้งละหนึ่งแถวแทนที่จะเก็บแถวทั้งหมดในหน่วยความจำ คุณส่ง Node.js ReadStream (ใน Node.js) หรืออ็อบเจกต์ File (ในเบราว์เซอร์) และ PapaParse จัดการการแบ่งเป็น chunk ภายใน ไม่ต้องต่อ stream pipeline — แค่ callback ใช้เมื่อต้องการความสอดคล้องกับ RFC 4180 โดยไม่ต้องดึง csv-parse มาใช้
import Papa from 'papaparse'
import { createReadStream } from 'node:fs'
let rowCount = 0
const errors = []
const fileStream = createReadStream('warehouse-inventory.csv')
Papa.parse(fileStream, {
header: true,
dynamicTyping: true,
step(result) {
// ประมวลผลทีละแถว — หน่วยความจำคงที่
rowCount++
if (result.data.quantity === 0) {
errors.push(`แถว ${rowCount}: ${result.data.sku} หมดสต็อก`)
}
},
complete() {
console.log(`ประมวลผลแล้ว ${rowCount} แถว`)
if (errors.length > 0) {
console.log(`พบปัญหา: ${errors.length}`)
errors.forEach(e => console.log(` ${e}`))
}
},
error(err) {
console.error('การ parse ล้มเหลว:', err.message)
},
})ข้อผิดพลาดที่พบบ่อย
ปัญหา: CSV ไม่ใช่ JSON การส่งสตริง CSV ดิบไปยัง JSON.parse() จะเกิด SyntaxError เพราะคอมม่าและขึ้นบรรทัดใหม่ไม่ใช่ไวยากรณ์ JSON ที่ถูกต้อง
วิธีแก้: Parse CSV เป็นอ็อบเจกต์ JavaScript ก่อนโดยใช้ split() หรือ library จากนั้นใช้ JSON.stringify() เพื่อสร้าง JSON เรียก JSON.parse() เฉพาะกับสตริงที่เป็น JSON ที่ถูกต้องแล้วเท่านั้น
const csv = 'name,email\nสมชาย ใจดี,somchai@nexuslabs.io' const data = JSON.parse(csv) // SyntaxError: Unexpected token 'a'
const csv = 'name,email\nสมชาย ใจดี,somchai@nexuslabs.io'
const lines = csv.trim().split('\n')
const headers = lines[0].split(',')
const rows = lines.slice(1).map(line =>
Object.fromEntries(headers.map((h, i) => [h, line.split(',')[i]]))
)
const json = JSON.stringify(rows, null, 2) // สตริง JSON ที่ถูกต้องปัญหา: การเรียก toString() บนอ็อบเจกต์ JavaScript คืนสตริงที่ไม่มีประโยชน์ '[object Object]' แทนที่จะเป็นข้อมูลจริง สิ่งนี้ทำลาย output การแปลง CSV เป็น JSON อย่างเงียบๆ
วิธีแก้: ใช้ JSON.stringify() เสมอเพื่อแปลงอ็อบเจกต์ JavaScript เป็นสตริง JSON toString() มีไว้สำหรับการ coerce primitive เป็นสตริง ไม่ใช่สำหรับ serialization
const row = { server: 'api-gateway', port: 8080 }
const output = row.toString()
// "[object Object]" — ข้อมูลหายไปconst row = { server: 'api-gateway', port: 8080 }
const output = JSON.stringify(row, null, 2)
// '{"server":"api-gateway","port":8080}'ปัญหา: การ split(",") แบบง่ายพังเมื่อค่า CSV มีคอมม่าภายใน field ที่มีเครื่องหมายคำพูด: "Widget, Large" กลายเป็นสองค่าแยกกันแทนที่จะเป็นหนึ่ง
วิธีแก้: ใช้ PapaParse หรือ csv-parse สำหรับข้อมูล CSV ที่คุณไม่ได้ควบคุมทั้งหมด หากต้อง parse แบบ manual ให้เขียน state-machine parser ที่ติดตามว่าตำแหน่งปัจจุบันอยู่ใน field ที่มีเครื่องหมายคำพูดหรือไม่
const line = '"Widget, Large","Premium quality",29.99'
const values = line.split(',')
// ["\"Widget", " Large\"", "\"Premium quality\"", "29.99"]
// 4 ค่าแทนที่จะเป็น 3 — field แรกถูกแบ่งผิดimport Papa from 'papaparse'
const { data } = Papa.parse('"Widget, Large","Premium quality",29.99')
// data[0] = ["Widget, Large", "Premium quality", "29.99"]
// 3 ค่า parse ถูกต้องปัญหา: หากไม่ coerce ชนิดข้อมูล port: "8080" จะยังคงเป็นสตริงใน JSON แทนที่จะเป็นตัวเลข ระบบ downstream ที่คาดหวังชนิดข้อมูลตัวเลขจะปฏิเสธหรือจัดการข้อมูลผิดพลาด
วิธีแก้: ใช้การ coerce ชนิดข้อมูลแบบชัดเจนระหว่างขั้นตอนการ mapping หรือใช้ PapaParse พร้อม dynamicTyping: true ควรตั้งใจเสมอว่า field ใดควรเป็นตัวเลข
const row = { port: '8443', debug: 'true', workers: '4' }
JSON.stringify(row)
// {"port":"8443","debug":"true","workers":"4"} — ทุกอย่างเป็นสตริงconst row = {
port: Number('8443'), // 8443
debug: 'true' === 'true', // true
workers: Number('4'), // 4
}
JSON.stringify(row)
// {"port":8443,"debug":true,"workers":4} — ชนิดข้อมูลถูกต้องการ Parse แบบ Manual กับ Library — เปรียบเทียบอย่างรวดเร็ว
สำหรับ script ขนาดเล็กที่คุณควบคุมรูปแบบ CSV และรู้ว่าไม่มี field ที่มีเครื่องหมายคำพูด วิธีการ split() + JSON.stringify() ที่ built-in ใช้งานได้และไม่ต้องพึ่งพา dependency ใดๆ สำหรับระบบ production ที่ประมวลผลไฟล์ CSV ที่ผู้ใช้อัปโหลด ใช้ PapaParse ในเบราว์เซอร์หรือ csv-parse ใน Node.js — ทั้งคู่จัดการ RFC 4180 ได้อย่างถูกต้องและรองรับ streaming แพ็กเกจ csvtojson เป็นตัวเดียวที่ output JSON โดยตรง จัดการทั้งการ parse และการ serialize ในการเรียกครั้งเดียว เมื่อต้องการเส้นทางที่เร็วที่สุดจากการวางถึงผลลัพธ์ เครื่องมือแปลง CSV เป็น JSON จัดการทั้งหมดในเบราว์เซอร์โดยไม่ต้องตั้งค่าใดๆ
คำถามที่พบบ่อย
วิธีแปลง CSV เป็น JSON ใน JavaScript โดยไม่ใช้ไลบรารี?
แบ่งสตริง CSV ด้วยขึ้นบรรทัดใหม่เพื่อรับแถว ดึง header จากแถวแรกด้วย split(",") จากนั้น map แถวที่เหลือเป็นอ็อบเจกต์โดยใช้ header เป็นคีย์ สุดท้ายใช้ JSON.stringify(array, null, 2) เพื่อสร้างสตริง JSON ที่อ่านง่าย วิธีนี้ใช้ได้ดีกับไฟล์ CSV เรียบง่ายที่คุณควบคุมรูปแบบและรู้ว่าไม่มี field ที่มีเครื่องหมายคำพูดหรือคอมม่าฝังอยู่ สำหรับข้อมูลที่ส่งออกจากสเปรดชีตหรือระบบภายนอก field ที่มีเครื่องหมายคำพูดและค่าหลายบรรทัดจะทำให้การแบ่งแบบง่ายพัง — ควรเปลี่ยนไปใช้ PapaParse หรือ csv-parse ในกรณีเหล่านั้น สำหรับไฟล์ขนาดเล็กที่ประมวลผลในเบราว์เซอร์ วิธีที่ไม่ต้องพึ่งพา dependency นี้เหมาะที่สุด
const csv = `name,email,department
สมชาย ใจดี,somchai@nexuslabs.io,Engineering
นภา วงศ์สุข,napa@nexuslabs.io,Product`
const lines = csv.trim().split('\n')
const headers = lines[0].split(',')
const rows = lines.slice(1).map(line => {
const values = line.split(',')
return Object.fromEntries(headers.map((h, i) => [h.trim(), values[i]?.trim()]))
})
console.log(JSON.stringify(rows, null, 2))
// [
// { "name": "สมชาย ใจดี", "email": "somchai@nexuslabs.io", "department": "Engineering" },
// { "name": "นภา วงศ์สุข", "email": "napa@nexuslabs.io", "department": "Product" }
// ]ความแตกต่างระหว่าง JSON.stringify() และ toString() สำหรับอ็อบเจกต์คืออะไร?
toString() บนอ็อบเจกต์ธรรมดาจะคืนสตริงที่ไม่มีประโยชน์ "[object Object]" — ไม่บอกอะไรเกี่ยวกับข้อมูลจริง JSON.stringify() สร้างสตริง JSON ที่ถูกต้องพร้อม key และ value ทั้งหมดที่ serialize อย่างถูกต้อง รวมถึงอ็อบเจกต์และอาร์เรย์ที่ซ้อนกัน ใช้ JSON.stringify() เสมอเมื่อต้องการแปลงอ็อบเจกต์ JavaScript (เช่นแถวที่ได้จาก CSV) เป็นสตริง JSON ในการย้อนกลับการดำเนินการ — สร้างอ็อบเจกต์ JavaScript ที่มีชีวิตจากสตริง JSON — ใช้ JSON.parse() ซึ่งเป็นการดำเนินการผกผันของ JSON.stringify() ฟังก์ชันทั้งสองนี้สร้างวงจรสมบูรณ์: stringify เพื่อบันทึกหรือส่งข้อมูล parse เพื่อนำกลับมาใช้
const row = { name: 'สมชาย ใจดี', role: 'Engineer' }
console.log(row.toString()) // "[object Object]"
console.log(JSON.stringify(row)) // '{"name":"สมชาย ใจดี","role":"Engineer"}'วิธีจัดการกับ field ใน CSV ที่มีคอมม่าหรือเครื่องหมายคำพูด?
RFC 4180 กำหนดว่า field ที่มีคอมม่า ขึ้นบรรทัดใหม่ หรือเครื่องหมายคำพูดคู่ต้องห่อด้วยเครื่องหมายคำพูดคู่ โดยเครื่องหมายคำพูดที่ฝังอยู่จะถูก escape ด้วยการซ้ำกัน ("" ภายใน field ที่มีเครื่องหมายคำพูดแทน quote เดี่ยวหนึ่งตัว) การใช้ split(",") แบบง่ายจะพังกับไฟล์เหล่านี้ — ขอบเขต field ไม่ใช่คอมม่าธรรมดาอีกต่อไป ใช้ PapaParse หรือ csv-parse สำหรับข้อมูลที่ใช้งานจริง หรือเขียน state-machine parser ที่ติดตามว่าอยู่ใน field ที่มีเครื่องหมายคำพูดหรือไม่ การเขียน state machine ที่ถูกต้องตั้งแต่ต้นนั้นซับซ้อนกว่าที่คิด: ต้องจัดการเครื่องหมายคำพูดที่จุดเริ่มต้นของ field เครื่องหมายคำพูด escape กลางคัน ขึ้นบรรทัดใหม่ภายใน field ที่มีเครื่องหมายคำพูด และรูปแบบ line ending ที่ต่างกัน (CRLF กับ LF) สำหรับข้อมูล CSV ที่ซับซ้อนกว่าระดับทดสอบ ควรใช้ไลบรารีที่ผ่านการทดสอบมาแล้ว
// PapaParse จัดการ RFC 4180 ได้อย่างถูกต้อง
import Papa from 'papaparse'
const csv = `product,description,price
"Widget, Large","A big ""widget""",29.99
Bolt,Standard bolt,1.50`
const { data } = Papa.parse(csv, { header: true })
console.log(JSON.stringify(data, null, 2))
// description field มีค่าที่ถูกต้อง: A big "widget"แปลง CSV เป็น JSON โดยตรงในเบราว์เซอร์ได้ไหม?
ได้ ทั้ง JSON.stringify() และ JSON.parse() มีอยู่ใน engine ของเบราว์เซอร์ทุกตัว สำหรับขั้นตอนการ parse CSV คุณสามารถแบ่งด้วยขึ้นบรรทัดใหม่และคอมม่าสำหรับไฟล์เรียบง่าย หรือรวม PapaParse ผ่าน CDN (ไม่มี dependency สำหรับ Node.js) การแปลงทั้งหมดเกิดขึ้นฝั่ง client โดยไม่ต้องส่งข้อมูลไปเซิร์ฟเวอร์ ซึ่งมีประโยชน์สำหรับความเป็นส่วนตัวของไฟล์ — ข้อมูล CSV ดิบไม่เคยออกจากเครื่องของผู้ใช้ เมื่อผู้ใช้อัปโหลดไฟล์ CSV ผ่านองค์ประกอบ <input type="file"> เมธอด file.text() ของ File API คืน Promise ที่ resolve เป็นเนื้อหาของไฟล์เป็นสตริง ซึ่งสามารถส่งไปยังฟังก์ชันแปลงได้ ทำให้การแปลง CSV เป็น JSON ในเบราว์เซอร์อย่างสมบูรณ์เป็นไปได้จริงสำหรับ dashboard เครื่องมือสำหรับนักพัฒนา และแอปที่ต้องประมวลผลข้อมูลที่อัปโหลดโดยไม่ต้องมี backend
// เบราว์เซอร์: ผู้ใช้อัปโหลดไฟล์ CSV
const fileInput = document.querySelector('input[type="file"]')
fileInput.addEventListener('change', async (event) => {
const file = event.target.files[0]
const text = await file.text()
const lines = text.trim().split('\n')
const headers = lines[0].split(',')
const rows = lines.slice(1).map(line =>
Object.fromEntries(headers.map((h, i) => [h.trim(), line.split(',')[i]?.trim()]))
)
console.log(JSON.stringify(rows, null, 2))
})วิธี parse ค่าตัวเลขและบูลีนจาก CSV แทนที่จะเก็บทุกอย่างเป็นสตริง?
CSV ไม่มีระบบชนิดข้อมูล — ทุก field เป็นสตริง คุณต้อง coerce ค่าระหว่างขั้นตอนการ mapping ตรวจสอบรูปแบบตัวเลขด้วย Number() หรือ parseFloat() แปลง "true"/"false" เป็นบูลีน และจัดการสตริงว่างเป็น null ระวัง field ที่ดูเหมือนตัวเลขแต่ต้องเป็นสตริง: รหัสไปรษณีย์เช่น "07302" จะสูญเสียเลขศูนย์นำหน้าเมื่อ coerce ด้วย Number() และหมายเลขโทรศัพท์หรือรหัสสินค้าที่มีตัวเลขก็มีปัญหาเดียวกัน ไลบรารี csvtojson ทำการ coerce ชนิดข้อมูลอัตโนมัติผ่านตัวเลือก colParser ซึ่งให้คุณระบุฟังก์ชันแปลงต่อคอลัมน์และแทนที่การตรวจจับอัตโนมัติสำหรับคอลัมน์ที่มีปัญหา ตัวเลือก dynamicTyping ของ PapaParse ใช้การ coerce เดียวกันกับทุกคอลัมน์
function coerceValue(val) {
if (val === '') return null
if (val === 'true') return true
if (val === 'false') return false
const num = Number(val)
if (!isNaN(num) && val.trim() !== '') return num
return val
}
// ใช้ระหว่างการ map จาก CSV เป็นอ็อบเจกต์
const row = { port: coerceValue('8443'), debug: coerceValue('true'), host: coerceValue('api.internal') }
// { port: 8443, debug: true, host: "api.internal" }วิธีเขียนผลลัพธ์ CSV เป็น JSON ลงไฟล์ใน Node.js?
ใช้ fs.writeFileSync() พร้อมผลลัพธ์จาก JSON.stringify() อาร์กิวเมนต์ที่สามของ JSON.stringify ควบคุมการย่อหน้า — ส่ง 2 สำหรับการย่อหน้าสองช่อง หรือ "\t" สำหรับ tab เพื่ออ่านไฟล์กลับคืน ใช้ JSON.parse(fs.readFileSync(path, "utf8")) ซึ่งจะสร้างอาร์เรย์ JavaScript ของอ็อบเจกต์ขึ้นใหม่ หากเขียนไฟล์ในบริบท async (ภายใน async function หรือที่ระดับบนสุดของ ES module) ควรใช้ fs.promises.writeFile() เพื่อหลีกเลี่ยงการบล็อก event loop ขณะเขียนไฟล์ สำหรับผลลัพธ์ JSON ขนาดใหญ่หลายเมกะไบต์ ควรพิจารณาใช้ JSON stream ไปยัง WriteStream แทนการสร้างสตริงทั้งหมดในหน่วยความจำก่อนเขียน
import { writeFileSync, readFileSync } from 'node:fs'
// เขียน
const jsonOutput = JSON.stringify(rows, null, 2)
writeFileSync('employees.json', jsonOutput, 'utf8')
// อ่านกลับ
const parsed = JSON.parse(readFileSync('employees.json', 'utf8'))
console.log(Array.isArray(parsed)) // true
console.log(parsed[0].name) // "สมชาย ใจดี"เครื่องมือที่เกี่ยวข้อง
Alex is a front-end and Node.js developer with extensive experience building web applications and developer tooling. He is passionate about web standards, browser APIs, and the JavaScript ecosystem. In his spare time he contributes to open-source projects and writes about modern JavaScript patterns, performance optimisation, and everything related to the web platform.
Sophie is a full-stack developer focused on TypeScript across the entire stack — from React frontends to Express and Fastify backends. She has a particular interest in type-safe API design, runtime validation, and the patterns that make large JavaScript codebases stay manageable. She writes about TypeScript idioms, Node.js internals, and the ever-evolving JavaScript module ecosystem.