You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改PHP代码实现CSV文件的多行数据添加功能?

实现多行客户信息收集并导出CSV的表单

下面是修改后的完整代码,已实现动态添加表单行、多行数据验证及CSV导出功能:

<?php
// 初始化错误信息数组
$errors = array();

if (isset($_POST['submit'])) {
    // 获取公司名称
    $Companyname = $_POST['Companyname'];
    
    // 验证公司名称
    if (empty($Companyname)) {
        $errors[] = "公司名称为必填项。";
    }

    // 获取多行表单数据
    $firstnames = $_POST['FirstName'] ?? [];
    $lastnames = $_POST['LastName'] ?? [];
    $DateofBirths = $_POST['DateofBirth'] ?? [];
    $CDLs = $_POST['CDL'] ?? [];
    $Countries = $_POST['Country'] ?? [];
    $States = $_POST['State'] ?? [];

    // 逐行验证数据
    foreach ($firstnames as $index => $firstname) {
        // 跳过空行(可选:若需强制所有添加行必须填写,可移除此判断)
        if (empty($firstname) && empty($lastnames[$index]) && empty($DateofBirths[$index]) && empty($CDLs[$index]) && empty($Countries[$index]) && empty($States[$index])) {
            continue;
        }

        // 验证名字
        if (empty($firstname)) {
            $errors[] = "第 ".($index+1)." 行的名字为必填项。";
        }

        // 验证姓氏
        if (empty($lastnames[$index])) {
            $errors[] = "第 ".($index+1)." 行的姓氏为必填项。";
        }

        // 验证出生日期
        if (empty($DateofBirths[$index])) {
            $errors[] = "第 ".($index+1)." 行的出生日期为必填项。";
        }

        // 验证CDL编号
        if (empty($CDLs[$index])) {
            $errors[] = "第 ".($index+1)." 行的CDL编号为必填项。";
        }

        // 验证国家
        if (empty($Countries[$index])) {
            $errors[] = "第 ".($index+1)." 行的国家为必填项。";
        }

        // 验证州/省
        if (empty($States[$index])) {
            $errors[] = "第 ".($index+1)." 行的州/省为必填项。";
        }
    }

    // 无错误时生成CSV
    if (empty($errors)) {
        // CSV表头
        $Content = "firstname,lastname,DateofBirth,CDL,Country,State\n";

        // 逐行添加数据到CSV
        foreach ($firstnames as $index => $firstname) {
            // 跳过空行
            if (empty($firstname) && empty($lastnames[$index]) && empty($DateofBirths[$index]) && empty($CDLs[$index]) && empty($Countries[$index]) && empty($States[$index])) {
                continue;
            }

            // 转义特殊字符,避免CSV格式错乱
            $fn = str_replace('"', '""', $firstname);
            $ln = str_replace('"', '""', $lastnames[$index]);
            $dob = str_replace('"', '""', $DateofBirths[$index]);
            $cdl = str_replace('"', '""', $CDLs[$index]);
            $country = str_replace('"', '""', $Countries[$index]);
            $state = str_replace('"', '""', $States[$index]);

            // 用双引号包裹字段,处理含逗号的数据
            $Content .= "\"$fn\",\"$ln\",\"$dob\",\"$cdl\",\"$country\",\"$state\"\n";
        }

        // 设置文件名并导出CSV
        $FileName = $Companyname . "-" . date("d-m-y-h:i:s") . ".csv";
        header('Content-Type: application/csv');
        header('Content-Disposition: attachment; filename="' . $FileName . '"');
        echo $Content;
        exit();
    }
}

// 显示错误信息
if (!empty($errors)) {
    foreach ($errors as $error) {
        echo '<p style="color:#ff0000">' . $error . '</p>';
    }
}
?>

<!-- 带动态行功能的HTML表单 -->
<form action="" method="post">
    <label>公司名称</label>
    <input type="text" name="Companyname" required value="">
    <br><br>

    <!-- 表单行容器 -->
    <div id="formRows">
        <!-- 初始表单行 -->
        <div class="formRow">
            <label>名字</label>
            <input type="text" name="FirstName[]" required value="">

            <label>姓氏</label>
            <input type="text" name="LastName[]" required value="">

            <label>出生日期</label>
            <input type="date" name="DateofBirth[]" required value="">

            <label>CDL #</label>
            <input type="text" name="CDL[]" required value="">

            <label>国家</label>
            <select name="Country[]" required>
                <option value="">选择国家</option>
                <option value="US">美国</option>
                <option value="CN">加拿大</option>
                <option value="MX">墨西哥</option>
            </select>

            <label>州/省:</label>
            <select name="State[]" required>
                <option value="">选择州/省</option>
                <option value="AL">阿拉巴马州</option>
                <option value="AK">阿拉斯加州</option>
                <option value="AZ">亚利桑那州</option>
                <option value="AR">阿肯色州</option>
                <option value="CA">加利福尼亚州</option>
                <option value="CO">科罗拉多州</option>
                <option value="CT">康涅狄格州</option>
                <option value="DE">特拉华州</option>
                <option value="FL">佛罗里达州</option>
                <option value="GA">佐治亚州</option>
                <option value="HI">夏威夷州</option>
                <option value="ID">爱达荷州</option>
                <option value="IL">伊利诺伊州</option>
                <option value="IN">印第安纳州</option>
                <option value="IA">爱荷华州</option>
                <option value="KS">堪萨斯州</option>
                <option value="KY">肯塔基州</option>
                <option value="LA">路易斯安那州</option>
                <option value="ME">缅因州</option>
                <option value="MD">马里兰州</option>
                <option value="MA">马萨诸塞州</option>
                <option value="MI">密歇根州</option>
                <option value="MN">明尼苏达州</option>
                <option value="MS">密西西比州</option>
                <option value="MT">蒙大拿州</option>
                <option value="NE">内布拉斯加州</option>
                <option value="NV">内华达州</option>
                <option value="NH">新罕布什尔州</option>
                <option value="NJ">新泽西州</option>
                <option value="NM">新墨西哥州</option>
                <option value="NY">纽约州</option>
                <option value="NC">北卡罗来纳州</option>
                <option value="ND">北达科他州</option>
                <option value="OH">俄亥俄州</option>
                <option value="OK">俄克拉荷马州</option>
                <option value="OR">俄勒冈州</option>
                <option value="PA">宾夕法尼亚州</option>
                <option value="RI">罗得岛州</option>
                <option value="SC">南卡罗来纳州</option>
                <option value="SD">南达科他州</option>
                <option value="TN">田纳西州</option>
                <option value="TX">德克萨斯州</option>
                <option value="UT">犹他州</option>
                <option value="VT">佛蒙特州</option>
                <option value="VA">弗吉尼亚州</option>
                <option value="WA">华盛顿州</option>
                <option value="WV">西弗吉尼亚州</option>
                <option value="WI">威斯康星州</option>
                <option value="WY">怀俄明州</option>
            </select>

            <!-- 删除行按钮(仅第一行隐藏) -->
            <button type="button" class="removeRow" style="display:none;">删除此行</button>
        </div>
    </div>

    <br><br>
    <button type="button" id="addLine">Add a line</button>
    <input type="submit" name="submit" value="导出CSV">
    <input type="reset" name="reset" value="重置">
</form>

<script>
// 添加行功能
document.getElementById('addLine').addEventListener('click', function() {
    const formRows = document.getElementById('formRows');
    const firstRow = formRows.querySelector('.formRow');
    const newRow = firstRow.cloneNode(true);

    // 清空新行的输入值
    const inputs = newRow.querySelectorAll('input, select');
    inputs.forEach(input => {
        input.value = '';
        if (input.tagName === 'SELECT') {
            input.selectedIndex = 0;
        }
    });

    // 显示新行的删除按钮
    newRow.querySelector('.removeRow').style.display = 'inline-block';

    formRows.appendChild(newRow);
});

// 删除行功能
document.getElementById('formRows').addEventListener('click', function(e) {
    if (e.target.classList.contains('removeRow')) {
        const rows = document.querySelectorAll('.formRow');
        // 至少保留一行表单
        if (rows.length > 1) {
            e.target.parentElement.remove();
        }
    }
});
</script>

核心改动说明

  1. 表单字段数组化
    将原表单字段名改为FirstName[]、LastName[]格式,让PHP能接收多行数据为数组。

  2. 动态行操作

    • 点击「Add a line」克隆现有表单行,清空输入值并显示删除按钮。
    • 删除按钮仅在表单行数大于1时可用,避免无表单行的情况。
  3. 多行数据处理

    • PHP遍历数组逐行验证,给出带行号的错误提示。
    • 生成CSV时转义特殊字符,用双引号包裹字段,确保Excel等工具能正确解析。
    • 自动跳过空行,避免导出无效数据。

内容的提问来源于stack exchange,提问作者Poecifer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 13:57:34