如何在 php 中将 Json 转换为 CSV

Posted

技术标签:

【中文标题】如何在 php 中将 Json 转换为 CSV【英文标题】:How to convert Json to CSV in php 【发布时间】:2018-04-26 00:06:04 【问题描述】:

您好,我正在尝试将具有不同于普通数组结构的 json 文件转换为 csv 文件。我一直在尝试找到将其转换为 csv 文件的解决方案,但我找不到解决方案。

  <?php 
    $jsondata = '[
        "accession_number_original": "2012.11.45",
        "author_birth_date": [
          "1932"
        ],
        "author_date": [
          "1932"
        ],
        "author_death_date": [
          ""
        ],
        "author_description": [
          "American"
        ],
        "author_display": [
          "Day yon"
        ],
        "author_names_first": [
          "Day"
        ],
        "author_names_last": [
          "yon"
        ],
        "author_names_middle": [
          ""
        ],
        "image_height": "12 1/2",
        "image_width": "18 1/4",
        "jp2_image_url": "",
        "location_physical_location": "Art Gallery",
        "location_shelf_locator": "Unknown",
        "master_image_url": "",
        "note_provenance": "Gift of Gary Ginsberg and Susanna Aaron",
        "object_date": "1963/2010",
        "object_depth": "",
        "object_height": "",
        "object_width": "",
        "origin_datecreated_end": "1963",
        "origin_datecreated_start": "1963",
        "physical_description_extent": [
          "12 1/2 x 18 1/4"
        ],
        "physical_description_material": [
          "Gelatin silver print"
        ],
        "physical_description_technique": [
          "Gelatin silver print"
        ],
        "pid": "bdr:123456",
        "title": "As Demonstrators"
      ]';

    $jsonDecoded = json_decode($jsondata);
    print_r('<pre>');
    print_r($jsonDecoded);
    print_r('</pre>');
    $fh = fopen('fileout.csv', 'w');
    if (is_array($jsonDecoded))
      print_r('<-------- line variable output-------->');   
      foreach($jsonDecoded as $line)
            print_r('<pre>'); print_r($line); print_r('</pre>');
        print_r('<-------- data variable output-------->');
        if (is_array($line)||is_object($line))
          foreach($line as $data)
            fputcsv($fp,$data);
            
          
        
      
    

   fclose($fh);
   print_r('Converted Successfully');
?>

我尝试查看 *** 中的大多数类似问题,但没有一个具有我这样的数组,因此它们对我没有多大用处。

如果我使用单个 foreach,我会收到错误 Array to String Conversion failed 并且 Array 正在作为值而不是实际数据打印到 csv 文件中。

如果我使用两个 foreach 我会收到错误 fputcsv() 期望参数 2 是给定的数组字符串

var_dump 或 print_r 解码后的json结果如下

Array
(
[0] => stdClass Object
    (
        [accession_number_original] => 2012.11.45
        [author_birth_date] => Array
            (
                [0] => 1932
            )

        [author_date] => Array
            (
                [0] => 1932
            )

        [author_death_date] => Array
            (
                [0] => 
            )

        [author_description] => Array
            (
                [0] => American
            )

        [author_display] => Array
            (
                [0] => Day yon
            )

        [author_names_first] => Array
            (
                [0] => Day
            )

        [author_names_last] => Array
            (
                [0] => yon
            )

        [author_names_middle] => Array
            (
                [0] => 
            )

        [image_height] => 12 1/2
        [image_width] => 18 1/4
        [jp2_image_url] => 
        [location_physical_location] => Art Gallery
        [location_shelf_locator] => Unknown
        [master_image_url] => 
        [note_provenance] => Gift of Gary Ginsberg and Susanna Aaron
        [object_date] => 1963/2010
        [object_depth] => 
        [object_height] => 
        [object_width] => 
        [origin_datecreated_end] => 1963
        [origin_datecreated_start] => 1963
        [physical_description_extent] => Array
            (
                [0] => 12 1/2 x 18 1/4
            )

        [physical_description_material] => Array
            (
                [0] => Gelatin silver print
            )

        [physical_description_technique] => Array
            (
                [0] => Gelatin silver print
            )

        [pid] => bdr:123456
        [title] => As Demonstrators
    )
)

【问题讨论】:

在第一步中去掉数组(将 author_* 转换为字符串),然后它不会抛出数组到字符串错误 @moped 谢谢你的评论,你能多解释一下吗?我应该手动转换每个没有键值的数组还是有什么方法可以做到这一点。请耐心等待我刚开始学习 php。 检查我的答案,如果有不清楚的地方请在评论中询问 【参考方案1】:

正如我在评论中提到的,第一步是处理数组值,所以每一行都需要转换值(它只计算您提供的格式,如果有一个包含 2 个值的数组,只有第一个将传递给 csv)。

您修改后的源代码:

$jsonDecoded = json_decode($jsondata, true); // add true, will handle as associative array    
print_r('<pre>');
print_r($jsonDecoded);
print_r('</pre>');
$fh = fopen('fileout.csv', 'w');
if (is_array($jsonDecoded)) 
  print_r('<-------- line variable output-------->');   
  foreach ($jsonDecoded as $line) 
    // with this foreach, if value is array, replace it with first array value
    foreach ($line as $key => $value) 
        if (is_array($value)) 
            $line[$key] = $value[0];
        
    
    print_r('<pre>'); print_r($line); print_r('</pre>');
    // no need for foreach, as fputcsv expects array, which we already have
    if (is_array($line)) 
      fputcsv($fh,$line);
    
  

fclose($fh);
print_r('Converted Successfully');

执行后的脚本输出:

[output of your print_r($jsonDecoded);]

<-------- line variable output-------->

Array
(
    [accession_number_original] => 2012.11.45
    [author_birth_date] => 1932
    [author_date] => 1932
    [author_death_date] => 
    [author_description] => American
    [author_display] => Day yon
    [author_names_first] => Day
    [author_names_last] => yon
    [author_names_middle] => 
    [image_height] => 12 1/2
    [image_width] => 18 1/4
    [jp2_image_url] => 
    [location_physical_location] => Art Gallery
    [location_shelf_locator] => Unknown
    [master_image_url] => 
    [note_provenance] => Gift of Gary Ginsberg and Susanna Aaron
    [object_date] => 1963/2010
    [object_depth] => 
    [object_height] => 
    [object_width] => 
    [origin_datecreated_end] => 1963
    [origin_datecreated_start] => 1963
    [physical_description_extent] => 12 1/2 x 18 1/4
    [physical_description_material] => Gelatin silver print
    [physical_description_technique] => Gelatin silver print
    [pid] => bdr:123456
    [title] => As Demonstrators
)

Converted Successfully

【讨论】:

感谢您的解决方案,但没有任何内容被写入 csv 文件我有权写入该文件,只有空文件正在创建以及 print_r('
'); print_r($line); print_r('
');不提供任何输出。
在我的开发中运行良好,所以我认为它是您的源代码,在您的 json 字符串之后仅复制/粘贴这部分并再次检查文件 我已经编辑了我的答案,所以它包含你所有的源代码 + 需要的修复,一定要在文件顶部包含你的 $jsondata 谢谢@moped 我一直在努力将其从 3 天的第二个 foreach 转换为问题,非常感谢它工作正常。清除浏览器缓存并重新启动它工作的服务器后可能是缓存问题。如何在文件中添加标题?是否正确//在文件中创建标题。 $firstLineKeys = 假; foreach ($jsonDecoded as $line) if (empty($firstLineKeys)) $firstLineKeys = array_keys($line); fputcsv($fh, $firstLineKeys); 【参考方案2】:

使用的 PHPExcel 库可以帮助我将我的 json 文件转换为 excel 表。 https://github.com/PHPOffice/PHPExcel

                $keyName=array();
                $i=0;
                $current_data=file_get_contents($dir.$excelFileLocation,true);
                $excelFile=fopen($dir."ExcelTojson.xls","w+");
                $array_data=json_decode($current_data,true);
                foreach($array_data as $jsonValue)
                
                    foreach($jsonValue as $key => $value)
                    
                        if($i==0)
                        
                            $keyName[$i]=$key;
                            $i++;
                        
                        else
                          
                            $check=0;
                            for($j=0;$j<count($keyName);$j++)
                            
                                if($keyName[$j]==$key)
                                   
                                    $check=1;
                                    break;
                                
                            
                            if($check==0)
                            
                                $keyName[$i]=$key;
                                $i++;
                            
                        
                    
                
                $excelSheet = PHPExcel_IOFactory::load($dir."ExcelTojson.xls");
                $excelSheet->setActiveSheetIndex(0);
                $ascii=65;
                for($i=0;$i<count($keyName);$i++)
                
                    $excelSheet->getActiveSheet()->setCellValue(chr($ascii)."1",stripslashes($keyName[$i]));
                    $ascii+=1;
                
                $cellValue=2;
                foreach($array_data as $jsonValue)
                   
                    $ascii=65;
                    foreach($jsonValue as $key => $value)
                    
                        $excelSheet->getActiveSheet()->setCellValue(chr($ascii).$cellValue,stripslashes($value));
                        $ascii+=1;
                    
                    $cellValue+=1;
                

                $filename="ExcelTojson.xls";
                header('Content-Type: application/vnd.ms-excel');
                header('Content-Disposition: attachment;filename="'.$filename.'"');
                header('Cache-Control: max-age=0');
                $objWriter = PHPExcel_IOFactory::createWriter($excelSheet, 'Excel5');
                $objWriter->save('php://output');

【讨论】:

感谢您的回答,但根据自述文件,它无法读取 json。是我遗漏了什么还是您需要更具体的信息? 使用 json 解码读取你的 json 并存储到一个数组中的数组键和具有相同索引的另一个数组中的值 $excelSheet = PHPExcel_IOFactory::load($dir."ExcelTojson.xls"); $excelSheet->setActiveSheetIndex(0); $ASCII=65; for($i=0;$igetActiveSheet()->setCellValue(chr($ascii)."1",stripslashes($keyName[$i]) ); $ascii+=1; 这是一个矫枉过正的解决方案 + 你可以编辑你的答案,源代码在 cmets 中很难阅读;) 顺便说一句,您是否意识到您的答案是关于 XLS 而不是 CSV?澄清一下,CSV 并不总是用于 Excel 等表格处理器【参考方案3】:

这是我的数据:我使用的是 Drupal 8。但是,它是一样的。

数组 ( [0] => 数组 ( [webform_id] => 网络表单 [sid] => 1 [名称] => Question_1 [属性] => A1 [增量] => 0 [值] => 6 )

[1] => Array
    (
        [webform_id] => webform
        [sid] => 1
        [name] => Question_2
        [property] => A2
        [delta] => 0
        [value] => 4
    )

[2] => Array
    (
        [webform_id] => webform
        [sid] => 1
        [name] => Question_3
        [property] => A3
        [delta] => 0
        [value] => 2
    )

)

我的函数文件:

public function DisplayData() 
// Fetch the data.

$connection = \Drupal::service('database');
$query = $connection->query("SELECT * FROM webform");
$result = $query->fetchAll();

$jsonDecoded = json_decode(json_encode($result), TRUE);

//给我们的CSV文件命名。 $csvFileName = 'test.csv';

//Open file pointer.
$fp = fopen($csvFileName, 'w');

//Loop through the associative array.
foreach($jsonDecoded as $rows)
  //Write the row to the CSV file. fputcsv(file,fields,separator,enclosure)
  foreach ($rows as $key => $value)
    if (is_array($value))
      $rows[$key] = $value[0];
    

  
  if (is_array($rows)) 
    fputcsv($fp, $rows);
    $roka = array_flip($rows);

  


fputcsv($fp, array_merge($roka, $rows));
fclose($fp);

$build = [
  '#theme' => 'webpage',
];
return $build;

完成---

【讨论】:

您应该添加对您提出的解决方案的描述。 @Viktor 我认为即使在第二次 foreach 之后仍然存在数组元素,这也不起作用,因此 fputcsv 不会接受它们。检查 [author_birth_date] 你会明白我的意思。 另外,这可行: foreach ($jsonDecoded as $row) fputcsv($fp, (array) $row);

以上是关于如何在 php 中将 Json 转换为 CSV的主要内容,如果未能解决你的问题,请参考以下文章

如何在python中将csv转换为json?

如何在 HugSQL 结果中将返回的地图转换为 json csv

如何在 PySpark 中将字符串转换为字典 (JSON) 的 ArrayType

如何在 PHP 中将字符串转换为 JSON 对象

如何在 symfony2 中将 json 转换为 php 对象?

如何在 PHP 中将非 json 字符串转换为有效的 json 字符串