{"id":4394,"date":"2016-06-07T02:52:19","date_gmt":"2016-06-07T02:52:19","guid":{"rendered":"http:\/\/www.garysieling.com\/blog\/?p=4394"},"modified":"2016-06-07T02:52:19","modified_gmt":"2016-06-07T02:52:19","slug":"export-csv-file-solr-express-js-node","status":"publish","type":"post","link":"https:\/\/www.garysieling.com\/blog\/export-csv-file-solr-express-js-node\/","title":{"rendered":"Export a CSV file from Solr with Express.js \/ Node"},"content":{"rendered":"<p>There are several libraries which claim to help you export CSV or XLSX in Node, but I found it was simple to implement this manually. <\/p>\n<p>In this example, I&#8217;m going to export from a Solr resultset. To do this, you need to build a URL on your own, then write a get. Once this returns, you can parse the JSON, and pass it on to your CSV exporter.<\/p>\n<p>For completeness, here is the call to Solr:<\/p>\n<pre lang=\"javascript\">\nget({\n  host: \"localhost\", \n  port: 3000, \n  path: url\n}, \nfunction(res) {\n  res.setEncoding(\"utf8\");\n  let data = \"\";\n    \n  res.on(\"data\", (chunk) => {\n    data += chunk;\n  });\n    \n  res.on(\"end\", () => {\n    try {\n      let searchResults = JSON.parse(data);       \n      onComplete(searchResults);\n    } catch (e) {\n      console.log(e);\n    }\n  });\n)\n<\/pre>\n<p>To make a CSV file come out correctly, you need to set a couple headers correctly:<\/p>\n<pre>\nresponse.header(\"Content-Type\", \"text\/csv\");\nresponse.header(\"Content-Disposition\", \"attachment; filename=search.csv\");\n<\/pre>\n<p>You&#8217;ll also need to know the columns you&#8217;re exporting:<\/p>\n<pre lang=\"javascript\">\nlet columns = [\n  \"speakerName_s\",\n  \"download_s\",\n  \"title_s\"\n];\n<\/pre>\n<p>Once you do this, you&#8217;ll need to loop through the Solr results and print it out.<\/p>\n<pre lang=\"javascript\">\nresponse.write(columns.join(\",\"));\nresponse.write(\"\\n\");\n\nfor (let j = 0; j < searchResults.response.docs.length; j++) {\n  let doc = searchResults.response.docs[j];\n  let row = '';\n  \n  for (let i = 0; i < columns.length; i++) {\n    let column = columns[i];\n    let value: any = doc[column];\n          \n    if (value === undefined) {\n      value = '';\n    } else if (value instanceof Array) {\n      value = value.join(\",\");\n    } else {\n      value = value + '';\n    }\n          \n    row += '\"' + value.replace(\/\"\/g, '\"\"') + '\",'; \n  }\n        \n  response.write(row);\n  response.write(\"\\n\");\n}\n            \nresponse.end();\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Exporting a CSV from a Solr repository in Node<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[4],"tags":[302,388],"aioseo_notices":[],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/posts\/4394"}],"collection":[{"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/comments?post=4394"}],"version-history":[{"count":0,"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/posts\/4394\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/media?parent=4394"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/categories?post=4394"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/tags?post=4394"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}