API 參考
為希望整合或擴充 JSON 轉 CSV 轉換器功能的開發者提供的技術文件。
瀏覽器 API 用法
剪貼簿 API
此工具使用現代 Clipboard API 執行複製操作:
// Copy text to clipboard
async function copyToClipboard(text) {
try {
await navigator.clipboard.writeText(text);
console.log("Text copied to clipboard");
} catch (error) {
console.error("Failed to copy text: ", error);
}
}
瀏覽器支援:
- Chrome 66+
- Firefox 63+
- Safari 13.1+
- Edge 79+
檔案下載 API
CSV 檔案使用 Blob API 下載:
// Download CSV file
function downloadCSV(csvContent, filename) {
const blob = new Blob([csvContent], {
type: "text/csv;charset=utf-8",
});
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(url);
}
資料處理函式
JSON 驗證
// Validate JSON string
function validateJSON(jsonString) {
try {
const parsed = JSON.parse(jsonString);
return { valid: true, data: parsed };
} catch (error) {
return { valid: false, error: error.message };
}
}
CSV 轉換邏輯
// Convert JSON array to CSV
function jsonToCSV(jsonData, options = {}) {
const { delimiter = ",", includeHeaders = true, escapeQuotes = true } = options;
if (!Array.isArray(jsonData) || jsonData.length === 0) {
return "";
}
// Get all unique keys
const allKeys = new Set();
jsonData.forEach((item) => {
if (typeof item === "object" && item !== null) {
Object.keys(item).forEach((key) => allKeys.add(key));
}
});
const keys = Array.from(allKeys);
let csv = "";
// Add headers
if (includeHeaders) {
csv += keys.map((key) => escapeCSVValue(key, delimiter, escapeQuotes)).join(delimiter) + "\n";
}
// Add data rows
jsonData.forEach((item) => {
if (typeof item === "object" && item !== null) {
const row = keys.map((key) => {
const value = item[key];
return escapeCSVValue(value !== undefined ? String(value) : "", delimiter, escapeQuotes);
});
csv += row.join(delimiter) + "\n";
}
});
return csv;
}
CSV 值跳脫
// Escape CSV values
function escapeCSVValue(value, delimiter, escapeQuotes) {
if (!escapeQuotes) {
return value;
}
// If value contains delimiter, newline, or quotes, wrap in quotes
if (value.includes(delimiter) || value.includes("\n") || value.includes('"')) {
// Escape quotes: replace " with ""
return `"${value.replace(/"/g, '""')}"`;
}
return value;
}
設定選項
轉換選項介面
interface ConversionOptions {
delimiter: "," | ";" | "\t" | "|";
encoding: "utf-8" | "utf-16" | "gbk";
includeHeaders: boolean;
escapeQuotes: boolean;
}
預設設定
const defaultOptions = {
delimiter: ",",
encoding: "utf-8",
includeHeaders: true,
escapeQuotes: true,
};
資料結構
歷史記錄介面
interface HistoryRecord {
id: string;
input: string;
inputPreview: string;
output: string;
delimiter: string;
encoding: string;
includeHeaders: boolean;
escapeQuotes: boolean;
rows: number;
columns: number;
timestamp: string;
timestampMs: number;
}
統計資訊介面
interface ConversionStats {
rows: number;
columns: number;
size: string; // Formatted file size
}
錯誤處理
錯誤類型
enum ConversionError {
INVALID_JSON = "INVALID_JSON",
CONVERSION_FAILED = "CONVERSION_FAILED",
EMPTY_DATA = "EMPTY_DATA",
UNSUPPORTED_FORMAT = "UNSUPPORTED_FORMAT",
}
錯誤處理函式
// Handle conversion errors
function handleConversionError(error, jsonInput) {
switch (error.type) {
case "INVALID_JSON":
return {
message: "Invalid JSON format. Please check your input.",
field: "input",
severity: "error",
};
case "CONVERSION_FAILED":
return {
message: "Failed to convert JSON to CSV. Please check your data.",
field: "output",
severity: "error",
};
default:
return {
message: "An unexpected error occurred.",
field: "general",
severity: "error",
};
}
}
效能注意事項
大型資料集處理
// Process large datasets in chunks
function processLargeDataset(jsonData, chunkSize = 1000) {
const chunks = [];
for (let i = 0; i < jsonData.length; i += chunkSize) {
chunks.push(jsonData.slice(i, i + chunkSize));
}
return chunks.map((chunk) => jsonToCSV(chunk));
}
記憶體管理
// Monitor memory usage
function getMemoryUsage() {
if (performance.memory) {
return {
used: performance.memory.usedJSHeapSize,
total: performance.memory.totalJSHeapSize,
limit: performance.memory.jsHeapSizeLimit,
};
}
return null;
}
瀏覽器相容性
功能偵測
// Check browser capabilities
function checkBrowserSupport() {
return {
clipboardAPI: !!navigator.clipboard,
blobAPI: !!window.Blob,
fileAPI: !!window.File,
localStorage: !!window.localStorage,
jsonSupport: !!JSON.parse,
};
}
Polyfill
對於較舊的瀏覽器,可考慮使用以下 polyfill:
// Clipboard API polyfill
if (!navigator.clipboard) {
navigator.clipboard = {
writeText: function (text) {
return new Promise((resolve, reject) => {
const textArea = document.createElement("textarea");
textArea.value = text;
document.body.appendChild(textArea);
textArea.select();
try {
document.execCommand("copy");
resolve();
} catch (error) {
reject(error);
}
document.body.removeChild(textArea);
});
},
};
}
整合範例
React 元件整合
import React, { useState, useCallback } from "react";
function JSONToCSVConverter() {
const [jsonInput, setJsonInput] = useState("");
const [csvOutput, setCsvOutput] = useState("");
const [options, setOptions] = useState(defaultOptions);
const convertToCSV = useCallback(() => {
try {
const jsonData = JSON.parse(jsonInput);
const csv = jsonToCSV(jsonData, options);
setCsvOutput(csv);
} catch (error) {
console.error("Conversion failed:", error);
}
}, [jsonInput, options]);
return (
<div>
<textarea
value={jsonInput}
onChange={(e) => setJsonInput(e.target.value)}
placeholder="Enter JSON data..."
/>
<button onClick={convertToCSV}>Convert</button>
<textarea value={csvOutput} readOnly placeholder="CSV output will appear here..." />
</div>
);
}
Vue.js 整合
<template>
<div class="json-to-csv-converter">
<textarea v-model="jsonInput" placeholder="Enter JSON data..." @input="validateAndConvert" />
<div class="options">
<select v-model="options.delimiter">
<option value=",">Comma (,)</option>
<option value=";">Semicolon (;)</option>
<option value="\t">Tab</option>
<option value="|">Pipe (|)</option>
</select>
</div>
<textarea :value="csvOutput" readonly placeholder="CSV output will appear here..." />
</div>
</template>
<script>
export default {
data() {
return {
jsonInput: "",
csvOutput: "",
options: {
delimiter: ",",
includeHeaders: true,
escapeQuotes: true,
},
};
},
methods: {
validateAndConvert() {
try {
const jsonData = JSON.parse(this.jsonInput);
this.csvOutput = this.jsonToCSV(jsonData, this.options);
} catch (error) {
this.csvOutput = "";
}
},
jsonToCSV(jsonData, options) {
// Implementation here
},
},
};
</script>
測試
單元測試範例
// Jest test examples
describe("JSON to CSV Converter", () => {
test("converts simple array to CSV", () => {
const input = [
{ name: "John", age: 30 },
{ name: "Jane", age: 25 },
];
const expected = "name,age\nJohn,30\nJane,25\n";
expect(jsonToCSV(input)).toBe(expected);
});
test("handles special characters", () => {
const input = [{ name: "Smith, John", quote: 'He said "Hello"' }];
const expected = 'name,quote\n"Smith, John","He said ""Hello"""\n';
expect(jsonToCSV(input)).toBe(expected);
});
test("validates JSON input", () => {
const invalidJson = '{ name: "John" }'; // Missing quotes
const result = validateJSON(invalidJson);
expect(result.valid).toBe(false);
});
});