【问题标题】:How does one convert an object into CSV using JavaScript?如何使用 JavaScript 将对象转换为 CSV?
【发布时间】:2014-05-12 03:54:58
【问题描述】:

我想将此对象转换为 CSV 文件。列名应该是键,这是一小块数组。最后一个数组将只有一个类型(键),所有其他数组将具有相同的键但不同的值。

[{
Comment: "Good",
Experince Months: "4",
Experince Years: "4",
Score: "3",
Subject: "CPP",
Topic: "Scripting (mention details)"
},
{
Comment: "Excilent",
Experince Months: "6",
Experince Years: "6",
Score: "6",
Subject: "CSharp",
Topic: "WPF"
},
{
Anything else worth highlighting: "Web Specialist",
Result: "Selected",
Total Business Analysis Experience: false,
Total Project Management Experience: false,
Total Score: 75,
Total Server Side Development Experience: true,
Total Server Side Support Experience: true,
Total UI Development Experience: true,
Total UI Support Experience: true
}]

【问题讨论】:

  • 你可能想看看这个link。
  • 我想制作该对象的 Excel 文件
  • 你想用Javascript创建Excel文件吗???
  • 是的输出应该是CSV格式的文件,我想用excel打开它
  • @rdonatoiop 实际上我的对象格式是正确的

标签: javascript jquery arrays csv


【解决方案1】:

这是 TSV 的一个简单实现(对于 csv,请参阅对此答案的评论):

// Returns a csv from an array of objects with
// values separated by tabs and rows separated by newlines
function CSV(array) {
    // Use first element to choose the keys and the order
    var keys = Object.keys(array[0]);

    // Build header
    var result = keys.join("\t") + "\n";

    // Add the rows
    array.forEach(function(obj){
        result += keys.map(k => obj[k]).join("\t") + "\n";
    });

    return result;
}

【讨论】:

  • 唯一的事情 - 您创建 TSV(制表符分隔值),而不是 CSV。如果您需要 CSV - 用逗号替换 \t
  • 这仅适用于在值中没有任何字符的情况下,这些字符可能会以其他方式解释为 CSV,例如双引号和逗号。因此,如果此代码导致您的 Excel,... 无法处理,您可能知道原因。
【解决方案2】:

这是我对此事的动态和更复杂的方法。它应该涵盖支持简单值、对象(即,一行)和数组(即,带标题的多行)的可能性。

注意:就Dates 而言,我建议先将它们转换为时间戳,因为世界上各种不同的格式令人困惑。

function toCsv(obj, columnDelimiter, lineDelimiter) {
  // configure this according to your location and project needs:
  const COLUMN_SEPARATOR = ",";
  const NUMERIC_COMMA = ".";
  
  function convertSimpleValue(value, columnDelimiter) {
    if (value == null || value == undefined) {
      return "";
    }

    let type = typeof(value);
    columnDelimiter ||= COLUMN_SEPARATOR;

    value = String(value);
    if (type == "number" && NUMERIC_COMMA != ".") {
      value = value.replace(".", NUMERIC_COMMA);
    }
    // converting \n to \\n is not part of CSV!

    if (value.includes("\"")) {
      value = value.replace(/"/g, "\"\"");
    }
    if (value.includes("\"") || value.includes(columnDelimiter) || value.includes("\n")) {
      value = `"${value}"`;
    }
    return value;
  }

  function buildKeys(...objs) {
    let keys = [];
    for (let obj of objs) {
      for (let key in obj) {
        if (!keys.includes(key)) {
          keys.push(key);
        }
      }
    }
    return keys;
  }

  function convertObject(obj, columnDelimiter, keys) {
    if (obj == null || obj == undefined) {
      return "";
    }
    if (typeof(obj) != "object") {
      return convertSimpleValue(obj, columnDelimiter);
    }
    
    columnDelimiter ||= COLUMN_SEPARATOR;
    keys ||= buildKeys(obj);

    let values = [];
    // for..of works differently compared to Object.values() and Object.entries()
    for (let key of keys) {
      values.push(convertSimpleValue(obj[key], columnDelimiter));
    }
    return values.join(columnDelimiter);
  }

  function convertArray(arr, columnDelimiter, lineDelimiter) {
    if (arr == null || arr == undefined || !arr.length) {
      return "";
    }
    
    columnDelimiter ||= COLUMN_SEPARATOR;
    lineDelimiter ||= "\n";

    let keys = buildKeys(...arr);
    let lines = [ 
      keys.map(convertSimpleValue).join(columnDelimiter),
      ...arr.map(obj => convertObject(obj, columnDelimiter, keys))
    ];
    return lines.join(lineDelimiter);
  }

  if (Array.isArray(obj)) {
    return convertArray(obj, columnDelimiter, lineDelimiter);
  }
  return convertObject(obj, columnDelimiter);
}

我仍在学习最新的 ECMA 内容,因此可能会缩短一些内容。

测试:

console.log("string", toCsv("string"));
console.log("str-com", toCsv("string,part2"));
console.log("str-dq", toCsv("string\"part2"));
console.log("number", toCsv(123));
console.log("float", toCsv(123.456));
console.log("object", toCsv({ x: "val1", num: 2 }));
console.log("array", toCsv([
  { x: "val1", num: 21 }, 
  { x: "val2", num: 22 },
  { x: "val3", num: 23 },
  { x: "right\"there", s: "t;t", "y\"z": "line1\nline2" }
]));

【讨论】:

    【解决方案3】:

    安哈!!实际上,我有一个 PHP Class 可以很好地与 same json object key 配合使用(您在第三组中使用了不同的 json 键)。因此,如果您愿意,可以根据需要修改我的 PHP Export Class(针对不同的对象键)。在这里,我将解释示例并与您分享我的课程。希望,修改完这个类后你的愿望成真了:)

    PHP Export Class [Class.Export.php]

    <?php
    /**
     * Class Export
     * 
     * Send JSON data and make an array to save as Excel file
     * 
     * @author neeraj.singh
     * @version 1.0
     *
     */
    
    // Class Start Here
    class Export {
    
        /**
         * Set Excel file name
         *
         * @var string
         */
        public $filename = 'excel-doc';
    
        /**
         * Set Excel field title
         *
         * @var string
         */
        public $custom_titles;
    
        /**
         * Get JSON data and convert in Excel file
         */
        public function saveAsExcel() {
            $CSV = trim ( $_POST ['exportdata'] );
            if (function_exists ( 'json_decode' )) {
                $data = json_decode ( $CSV, true );
                if (count ( $data ) > 0) {
                    // call excel export
                    $this->_createExcelByArray ( $data );
                } else {
                    die ( "Sorry!! array not build." );
                }
            } else {
                die ( "Sorry!! json_decode not working on this server." );
            }
        }
    
        /**
         * Take an array and create
         * Excel file
         *
         * @param array $dataArray          
         */
        private function _createExcelByArray($dataArray) {
            // set excel file name
            $this->filename = 'DEMO-Excel' . '-' . date ( 'd-m-Y-H-s' );
            // get array field by first element of array
            foreach ( $dataArray [0] as $k => $v ) {
                $field [] = $k;
            }
            // get total no of field in array
            $totalFields = count ( $field );
            $i = $j = 0;
            // get array values
            foreach ( $dataArray as $v ) {
                for($j; $j < $totalFields; $j ++) {
                    $value [$i] [] = $v [$field [$j]];
                }
                $i ++;
                $j = 0;
            }
            $this->initExcel ( $field, $value );
        }
    
        /**
         * Creating an Excel file with array data
         *
         * @param array $titles         
         * @param array $array          
         */
        public function initExcel($titles, $array) {
            $data = NULL;
            if (! is_array ( $array )) {
                die ( 'The data supplied is not a valid array' );
            } else {
                $headers = $this->titles ( $titles );
                if (is_array ( $array )) {
                    foreach ( $array as $row ) {
                        $line = '';
                        foreach ( $row as $value ) {
                            if (! isset ( $value ) or $value == '') {
                                $value = "\t";
                            } else {
                                $value = str_replace ( '"', '""', $value );
                                $value = '"' . $value . '"' . "\t";
                            }
                            $line .= $value;
                        }
                        $data .= iconv ( "UTF-8", "GB18030//IGNORE", trim ( $line ) ) . "\n";
                    }
                    $data = str_replace ( "\r", "", $data );
                    $this->generate ( $headers, $data );
                }
            }
        }
    
        /**
         * Create excel header and
         * write data into file
         *
         * @param string $headers           
         * @param string $data          
         */
        private function generate($headers, $data) {
            $this->set_headers ();
            echo "$headers\n$data";
        }
    
        /**
         * Set Excel file field header
         *
         * @param array $titles         
         * @return string
         */
        public function titles($titles) {
            if (is_array ( $titles )) {
                $headers = array ();
                if (is_null ( $this->custom_titles )) {
                    if (is_array ( $titles )) {
                        foreach ( $titles as $title ) {
                            $headers [] = iconv ( "UTF-8", "GB18030//IGNORE", $title );
                        }
                    } else {
                        foreach ( $titles as $title ) {
                            $headers [] = iconv ( "UTF-8", "GB18030//IGNORE", $title->name );
                        }
                    }
                } else {
                    $keys = array ();
                    foreach ( $titles as $title ) {
                        $keys [] = iconv ( "UTF-8", "GB18030//IGNORE", $title->name );
                    }
                    foreach ( $keys as $key ) {
                        $headers [] = iconv ( "UTF-8", "GB18030//IGNORE", $this->custom_titles [array_search ( $key, $keys )] );
                    }
                }
                return implode ( "\t", $headers );
            }
        }
    
        /**
         * Set Response Header
         */
        private function set_headers() {
            $ua = $_SERVER ["HTTP_USER_AGENT"];
            $filename = $this->filename . ".xls";
            $encoded_filename = urlencode ( $filename );
            $encoded_filename = str_replace ( "+", "%20", $encoded_filename );
            header ( "Pragma: public" );
            header ( "Expires: 0" );
            header ( "Cache-Control: must-revalidate, post-check=0, pre-check=0" );
            header ( "Content-Type: application/vnd.ms-excel; charset=UTF-8" );
            header ( "Content-Type: application/force-download" );
            header ( "Content-Type: application/octet-stream" );
            header ( "Content-Type: application/download" );
            if (preg_match ( "/MSIE/", $ua )) {
                header ( 'Content-Disposition: attachment; filename="' . $encoded_filename . '"' );
            } else if (preg_match ( "/Firefox/", $ua )) {
                header ( 'Content-Disposition: attachment; filename*="utf8\'\'' . $filename . '"' );
            } else {
                header ( 'Content-Disposition: attachment; filename="' . $filename . '"' );
            }
            header ( "Content-Transfer-Encoding: binary" );
        }
    }
    // Class End Here
    

    好的,下面是 HTML 和 PHP Code 来演示它的工作原理。

    HTML Code:

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>JSON to Excel POC</title>    
        <script type="text/javascript">
        <!--    
        function excelExport() {
            // this is your json data as string or you can
            // use as object too
            var jsonObject = '[{ "Comment" : "Good", "ExperinceMonths" : "4", "ExperinceYears" : "4", "Score" : "3", "Subject" : "CPP", "Topic" : "Scripting (mention details)" }, { "Comment" : "Excilent", "ExperinceMonths" : "6", "ExperinceYears" : "6", "Score" : "6", "Subject" : "CSharp", "Topic" : "WPF" }]';     
            // create a form
            var form            = document.createElement('FORM');
            form.name           = 'exportform';
            form.id             = 'exportform';
            form.method         = 'POST';
            form.action         = './export.php';
            // create a hidden input inside form
            var hiddenInput         = document.createElement('INPUT');
            hiddenInput.type    = 'HIDDEN';
            hiddenInput.name    = 'exportdata';
            hiddenInput.id      = 'exportdata';
            hiddenInput.value   = jsonObject;
            // insert hidden element inside form
            form.appendChild(hiddenInput);
            // insert form inside body
            document.body.appendChild(form);
            // submit the form
            form.submit();
            // remoce the form
            document.body.removeChild(form);
            return true;
        }
        //-->
        </script>
        </head>
    <body>
        <input type="button" value="Export" onClick='excelExport(); return false;'>
    </body>
    </html>
    

    终于来了

    PHP Code [export.php]

    <?php
    // add Class Export File
    require_once 'Class.Export.php';
    // make a new onject of Class Export
    $export = new Export ();
    // Send POSt data to make
    // Excel File
    if(isset($_POST['exportdata'])){
        $export->saveAsExcel();
    }
    ?>
    

    希望,这段代码能帮助到人们,因为,分享总是关怀 :) 干杯!!

    【讨论】:

    • 嘿,谢谢你的帮助,但我没有使用 PHP,抱歉我之前没有提到,但我感谢你的帮助。我正在使用 JavaScript
    猜你喜欢
    • 2015-04-17
    • 1970-01-01
    • 2021-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-19
    • 2016-12-26
    • 2018-04-28
    相关资源
    最近更新 更多