php - PHP无序关联数组到CSV行匹配标题到键,根据需要创建新标题
问题描述
我有一系列数组,类似:
$my_array = {"foo"=>"bar", "sudo"=>"make_sandwhich", "bam"=>"bang"};
和一个类似的csv:
Header 1, Header 2, foo, Header 4 , bam , Header 5
Lorem. , Ipsum. , , cheesecake, Henrietta, Loreal
, , , , , New Hampshire
当我从头开始添加示例行时,我希望 csv 看起来像这样......
Header 1, Header 2, foo, Header 4 , bam , Header 5 , sudo
Lorem. , Ipsum. , , cheesecake, Henrietta, Loreal ,
, , , , , New Hampshire,
, , bar, , bang , , make_sandwhich
我试过弄乱 fputcsv,但它似乎没有任何接近我需要的功能。有没有办法做到这一点?
解决方案
它可以通过 fgetcsv 和 fputcsv 以及“一些”附加处理来实现。
阅读您的 csv 文件(第一行是标题),然后从您的输入行添加新标题。然后读取行,为新标题创建缺失数据,并在末尾添加一个包含所有标题的新行。然后只需将该数据写回 csv 文件。
a.csv - 输入:
Header 1, Header 2, foo, Header 4 , bam , Header 5
Lorem. , Ipsum. , , cheesecake, Henrietta, Loreal
, , , , , New Hampshire
代码:
<?php
$myArray = ["foo"=>"bar", "sudo"=>"make_sandwhich", "bam"=>"bang"];
$readHandle = fopen("a.csv", "r");
// get headers (first row)
$headers = fgetcsv($readHandle);
$allHeaders = [];
foreach ($headers as $header) {
$allHeaders[] = trim($header);
}
// add missing headers from the input data (so to headers from file add sudo header)
foreach (array_keys($myArray) as $data) {
if (!in_array($data, $allHeaders)) {
$allHeaders[] = $data;
}
}
var_dump($allHeaders);
// read all rows from the file and add the new headers
$rows = [];
while($row = fgetcsv($readHandle)) {
foreach ($allHeaders as $k => $header) {
$row[$k] = isset($row[$k]) ? trim($row[$k]) : '';
}
$rows[] = $row;
}
// add the new row from input data
$newRow = [];
foreach ($allHeaders as $header) {
$newRow[] = $myArray[$header] ?? '';
}
$rows[] = $newRow;
var_dump($rows);
fclose($readHandle);
// now write headers and rows to csv file
$writeHandle = fopen('b.csv', 'w+');
fputcsv($writeHandle, $allHeaders);
foreach ($rows as $row) {
fputcsv($writeHandle, $row);
}
fclose($writeHandle);
$所有标题:
array(7) {
[0]=>
string(8) "Header 1"
[1]=>
string(8) "Header 2"
[2]=>
string(3) "foo"
[3]=>
string(8) "Header 4"
[4]=>
string(3) "bam"
[5]=>
string(8) "Header 5"
[6]=>
string(4) "sudo"
}
$行:
array(3) {
[0]=>
array(7) {
[0]=>
string(6) "Lorem."
[1]=>
string(6) "Ipsum."
[2]=>
string(0) ""
[3]=>
string(10) "cheesecake"
[4]=>
string(9) "Henrietta"
[5]=>
string(6) "Loreal"
[6]=>
string(0) ""
}
[1]=>
array(7) {
[0]=>
string(0) ""
[1]=>
string(0) ""
[2]=>
string(0) ""
[3]=>
string(0) ""
[4]=>
string(0) ""
[5]=>
string(13) "New Hampshire"
[6]=>
string(0) ""
}
[2]=>
array(7) {
[0]=>
string(0) ""
[1]=>
string(0) ""
[2]=>
string(3) "bar"
[3]=>
string(0) ""
[4]=>
string(4) "bang"
[5]=>
string(0) ""
[6]=>
string(14) "make_sandwhich"
}
}
b.csv - 输出:
"Header 1","Header 2",foo,"Header 4",bam,"Header 5",sudo
Lorem.,Ipsum.,,cheesecake,Henrietta,Loreal,
,,,,,"New Hampshire",
,,bar,,bang,,make_sandwhich
我希望您不希望 csv 中的空格用于格式化。也可以这样做,但您需要保留每列中最长字符串的字符数,并将值填充到该长度。
推荐阅读
- .net - 禁用/删除 Razor 引擎模板缓存
- ruby-on-rails - Rails 助手 If 语句
- java - 如何将 Dialog 转换为 DialogFragment?
- python - 在 Python 中使用 selenium 抓取动态(AJAX)网站
- java - javax.validation.constraints.Pattern 验证类型类 java.lang.String[]
- java - java.lang.IllegalArgumentException:类 java.text.DecimalFormat 声明了多个名为 maximumIntegerDigits 的 JSON 字段 - Android OS 7 和 8
- c - 将作为第二个参数传递的函数应用于指针 s 指向的数组的每个索引的函数
- r - 替换数据集中的所有负值
- sql - SQL - 如果匹配则返回值,否则返回列表的第一项
- docker - 将 Docker 容器连接到特定的网络接口(例如 eth1)?