You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

109 regels
3.3 KiB

  1. const fs = require('fs-extra');
  2. const { toSystemPath } = require('../core/path');
  3. module.exports = {
  4. csv: async function(options) {
  5. let path = this.parse(options.path);
  6. let data = this.parse(options.data);
  7. let header = this.parse(options.header);
  8. let delimiter = this.parse(options.delimiter);
  9. let overwrite = this.parse(options.overwrite);
  10. if (typeof path != 'string') throw new Error('export.csv: path is required.');
  11. if (!Array.isArray(data) || !data.length) throw new Error ('export.csv: data is required.');
  12. delimiter = typeof delimiter == 'string' ? delimiter : ',';
  13. if (delimiter == '\\t') delimiter = '\t';
  14. const fd = await fs.open(toSystemPath(path), overwrite ? 'w' : 'wx');
  15. if (header) {
  16. await putcsv(fd, Object.keys(data[0]), delimiter);
  17. }
  18. for (let row of data) {
  19. await putcsv(fd, row, delimiter);
  20. }
  21. await fs.close(fd);
  22. return path;
  23. },
  24. xml: async function(options) {
  25. let path = this.parse(options.path);
  26. let data = this.parse(options.data);
  27. let root = this.parse(options.root);
  28. let item = this.parse(options.item);
  29. let overwrite = this.parse(options.overwrite);
  30. if (typeof path != 'string') throw new Error('export.xml: path is required.');
  31. if (!Array.isArray(data) || !data.length) throw new Error('export.xml: data is required.');
  32. root = typeof root == 'string' ? root : 'export';
  33. item = typeof item == 'string' ? item : 'item';
  34. const fd = await fs.open(toSystemPath(path), overwrite ? 'w' : 'wx');
  35. await fs.write(fd, `<?xml version="1.0" encoding="UTF-8" ?><${root}>`);
  36. for (let row of data) {
  37. await fs.write(fd, `<${item}>`);
  38. for (let prop in row) {
  39. await fs.write(fd, `<${prop}><![CDATA[${row[prop]}]]></${prop}>`);
  40. }
  41. await fs.write(fd, `</${item}>`);
  42. }
  43. await fs.write(fd, `</${root}>`);
  44. await fs.close(fd);
  45. return path;
  46. },
  47. };
  48. async function putcsv(fd, data, delimiter) {
  49. let str = '';
  50. if (typeof data != 'object') {
  51. throw new Error('putcsv: Invalid data.');
  52. }
  53. for (let prop in data) {
  54. if (data.hasOwnProperty(prop)) {
  55. let value = String(data[prop]);
  56. if (/["\n\r\t\s]/.test(value) || value.includes(delimiter)) {
  57. let escaped = false;
  58. str += '"';
  59. for (let i = 0; i < value.length; i++) {
  60. if (value.charAt(i) == '\\') {
  61. escaped = true;
  62. } else if (!escaped && value.charAt(i) == '"') {
  63. str += '"';
  64. } else {
  65. escaped = false;
  66. }
  67. str += value.charAt(i);
  68. }
  69. str += '"';
  70. } else {
  71. str += value;
  72. }
  73. str += delimiter;
  74. }
  75. }
  76. if (!str) {
  77. throw new Error('putcsv: No data.');
  78. }
  79. return fs.write(fd, str.substr(0, str.length - delimiter.length) + '\r\n');
  80. }