"use client"; import { useState } from "react"; import { FileSpreadsheet, Copy, Trash2 } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Textarea } from "@/components/ui/textarea"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { toast } from "sonner"; export default function CsvJsonPage() { const [input, setInput] = useState(""); const [output, setOutput] = useState(""); const copyToClipboard = async (text: string) => { if (!text) return; try { await navigator.clipboard.writeText(text); toast.success("已复制到剪贴板"); } catch { toast.error("复制失败"); } }; const csvToJson = () => { try { if (!input.trim()) return; const lines = input.trim().split('\n'); if (lines.length < 2) { toast.error("请输入至少包含标题和一行数据的 CSV"); return; } const headers = lines[0].split(',').map(h => h.trim()); const result = lines.slice(1).map(line => { const values = line.split(','); const obj: any = {}; headers.forEach((header, i) => { obj[header] = values[i]?.trim() || ""; }); return obj; }); setOutput(JSON.stringify(result, null, 2)); toast.success("转换成功"); } catch { toast.error("CSV 格式错误"); } }; const jsonToCsv = () => { try { if (!input.trim()) return; const data = JSON.parse(input); if (!Array.isArray(data) || data.length === 0) { toast.error("JSON 必须是包含对象的数组"); return; } const headers = Object.keys(data[0]); const csvLines = [ headers.join(','), ...data.map(row => headers.map(h => row[h]).join(',')) ]; setOutput(csvLines.join('\n')); toast.success("转换成功"); } catch { toast.error("JSON 格式错误或不是对象数组"); } }; const clearAll = () => { setInput(""); setOutput(""); }; return (

CSV / JSON 互转

表格数据与 JSON 格式相互转换

输入区域