这是您需要的数据输入表单生成脚本,它基于 HTML、CSS 和 JavaScript,只需运行即可在浏览器中动态生成一个完整的表单,并支持数据预览与导出。

<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">脚本生成 · 数据输入表单</title>
<!-- 干净样式,无外部依赖 -->
<style>
* {
box-sizing: border-box;
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Arial, sans-serif;
}
body {
background: #f4f7fc;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 2rem 1rem;
}
.container {
max-width: 840px;
width: 100%;
background: white;
border-radius: 28px;
padding: 2rem 2rem 2.5rem;
box-shadow: 0 12px 30px rgba(0, 20, 40, 0.08);
transition: all 0.2s;
}
h1 {
font-size: 1.9rem;
font-weight: 600;
margin-top: 0.2rem;
margin-bottom: 0.25rem;
color: #0b2b4a;
letter-spacing: -0.01em;
display: flex;
align-items: center;
gap: 0.5rem;
}
.subhead {
color: #49748f;
margin-bottom: 1.8rem;
font-size: 0.95rem;
border-left: 4px solid #7ab7d4;
padding-left: 1rem;
background: #f0f7fc;
border-radius: 0 12px 12px 0;
line-height: 1.4;
}
.subhead strong {
color: #1c4e6e;
}
.grid-2 {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1.25rem 1.5rem;
margin-bottom: 2rem;
}
.field-group {
display: flex;
flex-direction: column;
gap: 0.35rem;
}
.field-group label {
font-weight: 500;
font-size: 0.85rem;
color: #1d4a68;
letter-spacing: 0.02rem;
display: flex;
align-items: center;
gap: 0.3rem;
}
.field-group label i {
color: #6999b5;
font-style: normal;
font-weight: 400;
}
.field-group input,
.field-group select,
.field-group textarea {
background: #f9fcff;
border: 1px solid #dae6ed;
border-radius: 16px;
padding: 0.7rem 1rem;
font-size: 0.95rem;
transition: 0.2s;
outline: none;
width: 100%;
}
.field-group input:focus,
.field-group select:focus,
.field-group textarea:focus {
border-color: #2c7da0;
box-shadow: 0 0 0 3px rgba(44, 125, 160, 0.2);
background: white;
}
.field-group textarea {
resize: vertical;
min-height: 80px;
}
.full-width {
grid-column: span 2;
}
.action-bar {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
gap: 1rem 0.8rem;
margin-top: 0.5rem;
border-top: 1px solid #e6edf4;
padding-top: 1.8rem;
}
.btn-group {
display: flex;
flex-wrap: wrap;
gap: 0.6rem 0.8rem;
}
.btn {
border: none;
background: #eef4f8;
padding: 0.6rem 1.2rem;
border-radius: 40px;
font-weight: 500;
font-size: 0.9rem;
color: #1f4b66;
cursor: pointer;
transition: 0.15s;
display: inline-flex;
align-items: center;
gap: 0.4rem;
border: 1px solid transparent;
}
.btn-primary {
background: #1c6d8f;
color: white;
box-shadow: 0 4px 8px rgba(28, 109, 143, 0.15);
}
.btn-primary:hover {
background: #125474;
transform: scale(0.97);
box-shadow: 0 6px 12px rgba(28, 109, 143, 0.2);
}
.btn-outline {
background: white;
border-color: #cbdbe7;
color: #1f4b66;
}
.btn-outline:hover {
background: #f2f9ff;
border-color: #80b3cc;
}
.btn-danger {
background: #ffeae5;
color: #9f4d3c;
}
.btn-danger:hover {
background: #fcdbd2;
}
.btn-success {
background: #dff0e6;
color: #1c6f4b;
}
.btn-success:hover {
background: #cee7da;
}
.badge {
background: #e2ecf5;
border-radius: 40px;
padding: 0.25rem 1rem;
font-size: 0.8rem;
color: #1f4b66;
font-weight: 450;
}
.badge span {
font-weight: 700;
color: #0b3852;
}
#previewBox {
background: #f4faff;
border-radius: 20px;
padding: 1rem 1.3rem;
margin-top: 1.2rem;
border: 1px solid #d8e5ef;
font-size: 0.9rem;
color: #1a3d53;
word-break: break-word;
max-height: 180px;
overflow-y: auto;
white-space: pre-wrap;
font-family: 'SF Mono', 'Fira Code', monospace;
transition: 0.1s;
}
#previewBox:empty {
display: none;
}
.gen-note {
font-size: 0.8rem;
color: #618aa5;
margin-top: 0.6rem;
text-align: right;
}
@media (max-width: 540px) {
.container { padding: 1.5rem; }
.grid-2 { grid-template-columns: 1fr; gap: 1rem; }
.full-width { grid-column: span 1; }
.action-bar { flex-direction: column; align-items: stretch; }
}
</style>
</head>
<body>
<div class="container">
<h1>📋 表单生成器</h1>
<div class="subhead">
⚡ 由脚本动态生成 · 字段预设 <strong>5 项</strong>,实时预览 JSON 数据
</div>
<!-- 动态表单区域:由 JavaScript 注入 -->
<div id="formMount" class="grid-2"></div>
<!-- 操作栏 + 预览 -->
<div class="action-bar">
<div class="btn-group">
<button class="btn btn-primary" id="previewBtn">🔍 预览数据</button>
<button class="btn btn-success" id="exportBtn">📥 导出 JSON</button>
<button class="btn btn-danger" id="resetBtn">↺ 重置默认</button>
</div>
<div class="badge">
🧩 字段 <span id="fieldCount">0</span>
</div>
</div>
<!-- 实时预览面板 -->
<div id="previewBox" placeholder="点击 [预览数据] 或修改字段值…">▶ 点击预览 或 修改任意字段</div>
<div class="gen-note">* 脚本自动挂载表单,修改即收集</div>
</div>
<script>
(function() {
// ---------- 脚本生成:表单定义 ----------
// 核心数据结构:字段列表 (可自由扩展)
const FIELD_CONFIG = [
{ key: 'fullName', label: '👤 姓名', type: 'text', placeholder: '张三', defaultValue: '李华' },
{ key: 'email', label: '✉️ 邮箱', type: 'email', placeholder: 'name@example.com', defaultValue: 'lihua@demo.cn' },
{ key: 'age', label: '🎂 年龄', type: 'number', placeholder: '18-99', defaultValue: 28 },
{ key: 'role', label: '💼 角色', type: 'select', options: ['开发者', '设计师', '产品经理', '数据分析', '其他'], defaultValue: '开发者' },
{ key: 'comment', label: '📝 备注', type: 'textarea', placeholder: '可选填写…', defaultValue: '由脚本生成的表单' }
];
// DOM 元素
const mountEl = document.getElementById('formMount');
const previewBox = document.getElementById('previewBox');
const fieldCountSpan = document.getElementById('fieldCount');
const previewBtn = document.getElementById('previewBtn');
const exportBtn = document.getElementById('exportBtn');
const resetBtn = document.getElementById('resetBtn');
// 存储当前表单数据 (用于预览、导出)
let currentFormData = {};
// ---------- 核心:渲染表单 (生成 input/select/textarea) ----------
function renderForm() {
if (!mountEl) return;
// 清空挂载点
mountEl.innerHTML = '';
// 记录生成的字段名 (用于数据收集)
const fieldKeys = [];
FIELD_CONFIG.forEach((field, index) => {
const { key, label, type, placeholder, defaultValue, options } = field;
fieldKeys.push(key);
// 创建包裹容器
const group = document.createElement('div');
group.className = 'field-group';
// 备注占整行 (full-width)
if (key === 'comment') {
group.classList.add('full-width');
}
// ---------- label ----------
const labelEl = document.createElement('label');
labelEl.setAttribute('for', `field-${key}`);
labelEl.textContent = label || key;
// 可选小标记
group.appendChild(labelEl);
// ---------- 根据 type 创建输入控件 ----------
let inputEl = null;
if (type === 'select') {
// SELECT
inputEl = document.createElement('select');
inputEl.id = `field-${key}`;
inputEl.name = key;
// 填充 options
const opts = options || ['选项1', '选项2'];
opts.forEach(optText => {
const opt = document.createElement('option');
opt.value = optText;
opt.textContent = optText;
if (optText === (defaultValue || opts[0])) {
opt.selected = true;
}
inputEl.appendChild(opt);
});
// 设置默认值 (defaultValue 匹配)
if (defaultValue && opts.includes(defaultValue)) {
inputEl.value = defaultValue;
}
} else if (type === 'textarea') {
// TEXTAREA
inputEl = document.createElement('textarea');
inputEl.id = `field-${key}`;
inputEl.name = key;
inputEl.placeholder = placeholder || '';
inputEl.rows = 3;
inputEl.textContent = defaultValue || '';
} else {
// input (text, email, number, etc.)
inputEl = document.createElement('input');
inputEl.id = `field-${key}`;
inputEl.name = key;
inputEl.type = type === 'number' ? 'number' : (type || 'text');
inputEl.placeholder = placeholder || '';
// 处理 number 类型默认值
if (type === 'number') {
inputEl.value = defaultValue !== undefined ? defaultValue : '';
} else {
inputEl.value = defaultValue || '';
}
}
// 公共属性:设置 data-key 用于快速取值
if (inputEl) {
inputEl.dataset.fieldKey = key;
// 添加事件监听 —— 任何输入改变都更新预览 (自动收集)
inputEl.addEventListener('input', function(e) {
collectFormData();
updatePreview();
});
inputEl.addEventListener('change', function(e) {
// select 等 change 触发
collectFormData();
updatePreview();
});
}
group.appendChild(inputEl);
mountEl.appendChild(group);
// 存储初始默认值 (便于重置)
if (inputEl) {
// 对于 select 使用 value
const initVal = inputEl.value || defaultValue || '';
currentFormData[key] = initVal;
}
});
// 更新字段计数
if (fieldCountSpan) {
fieldCountSpan.textContent = fieldKeys.length;
}
// 初始收集数据 & 预览
collectFormData();
updatePreview();
}
// ---------- 收集表单数据到 currentFormData ----------
function collectFormData() {
const formElements = mountEl.querySelectorAll('input, select, textarea');
const data = {};
formElements.forEach(el => {
const key = el.dataset.fieldKey || el.name;
if (key) {
// 数字类型转数字 (保留原始输入)
if (el.type === 'number') {
const val = el.value.trim();
data[key] = val === '' ? '' : Number(val);
} else {
data[key] = el.value;
}
}
});
// 合并 (确保包含所有字段)
FIELD_CONFIG.forEach(f => {
if (!(f.key in data)) {
data[f.key] = f.defaultValue || '';
}
});
currentFormData = data;
return data;
}
// ---------- 更新预览面板 ----------
function updatePreview() {
if (!previewBox) return;
const data = currentFormData && Object.keys(currentFormData).length > 0
? currentFormData
: collectFormData();
try {
// 美化 JSON 输出
const jsonStr = JSON.stringify(data, null, 2);
previewBox.textContent = jsonStr;
} catch (e) {
previewBox.textContent = '⚠️ 数据序列化异常';
}
}
// ---------- 重置表单到默认值 ----------
function resetToDefault() {
const formElements = mountEl.querySelectorAll('input, select, textarea');
formElements.forEach(el => {
const key = el.dataset.fieldKey || el.name;
const fieldDef = FIELD_CONFIG.find(f => f.key === key);
if (!fieldDef) return;
const defaultVal = fieldDef.defaultValue !== undefined ? fieldDef.defaultValue : '';
if (el.tagName === 'SELECT') {
// 对于 select,尝试匹配默认值
const opts = fieldDef.options || [];
if (defaultVal && opts.includes(defaultVal)) {
el.value = defaultVal;
} else {
el.value = opts[0] || '';
}
} else if (el.type === 'number') {
el.value = defaultVal !== '' ? defaultVal : '';
} else {
el.value = defaultVal || '';
}
});
// 重新收集 & 预览
collectFormData();
updatePreview();
}
// ---------- 导出 JSON (下载) ----------
function exportJSON() {
const data = collectFormData();
const jsonStr = JSON.stringify(data, null, 2);
const blob = new Blob([jsonStr], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
const timestamp = new Date().toISOString().slice(0, 19).replace(/[:-]/g, '');
a.download = `表单数据_${timestamp}.json`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
// 反馈
previewBox.textContent = jsonStr;
// 小提示
const note = document.querySelector('.gen-note');
if (note) {
note.textContent = '✅ JSON 已导出 ' + new Date().toLocaleTimeString();
setTimeout(() => {
note.textContent = '* 脚本自动挂载表单,修改即收集';
}, 3000);
}
}
// ---------- 手动预览 (强调) ----------
function previewData() {
collectFormData();
updatePreview();
// 闪一下提示
if (previewBox) {
previewBox.style.background = '#e5f3ff';
setTimeout(() => {
previewBox.style.background = '#f4faff';
}, 300);
}
}
// ---------- 初始化绑定事件 ----------
function initEventListeners() {
if (previewBtn) previewBtn.addEventListener('click', previewData);
if (exportBtn) exportBtn.addEventListener('click', exportJSON);
if (resetBtn) resetBtn.addEventListener('click', resetToDefault);
}
// ---------- 启动:渲染表单,挂载事件 ----------
function init() {
renderForm();
initEventListeners();
// 额外:确保预览显示
if (previewBox && !previewBox.textContent.trim()) {
previewBox.textContent = '▶ 点击预览 或 修改任意字段';
}
}
// DOM 就绪执行
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();
</script>
</body>
</html>
表单生成与数据管理
您可以通过修改脚本开头的 FIELD_CONFIG 数组来定制表单字段,生成后,所有操作都围绕数据收集与导出展开。
- 动态表单生成:脚本根据
FIELD_CONFIG配置,自动创建包含文本、数字、下拉菜单和文本域等类型的表单字段。 - 实时数据预览:您修改任何字段的值,下方的预览面板都会立即以 JSON 格式显示当前表单的完整数据。
- 数据重置与导出:点击“重置默认”可恢复所有字段的初始值。“导出 JSON”则会将当前数据下载为一个格式化的 JSON 文件。