SheetClip.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /**
  2. * SheetClip - Spreadsheet Clipboard Parser
  3. * version 0.2
  4. *
  5. * This tiny library transforms JavaScript arrays to strings that are pasteable by LibreOffice, OpenOffice,
  6. * Google Docs and Microsoft Excel.
  7. *
  8. * Copyright 2012, Marcin Warpechowski
  9. * Licensed under the MIT license.
  10. * http://github.com/warpech/sheetclip/
  11. */
  12. /*jslint white: true*/
  13. (function (global) {
  14. "use strict";
  15. function countQuotes(str) {
  16. return str.split('"').length - 1;
  17. }
  18. var SheetClip = {
  19. /**
  20. * Decode spreadsheet string into array
  21. *
  22. * @param {String} str
  23. * @returns {Array}
  24. */
  25. parse: function (str) {
  26. var r, rLen, rows, arr = [], a = 0, c, cLen, multiline, last;
  27. rows = str.split('\n');
  28. if (rows.length > 1 && rows[rows.length - 1] === '') {
  29. rows.pop();
  30. }
  31. for (r = 0, rLen = rows.length; r < rLen; r += 1) {
  32. rows[r] = rows[r].split('\t');
  33. for (c = 0, cLen = rows[r].length; c < cLen; c += 1) {
  34. if (!arr[a]) {
  35. arr[a] = [];
  36. }
  37. if (multiline && c === 0) {
  38. last = arr[a].length - 1;
  39. arr[a][last] = arr[a][last] + '\n' + rows[r][0];
  40. if (multiline && (countQuotes(rows[r][0]) & 1)) { //& 1 is a bitwise way of performing mod 2
  41. multiline = false;
  42. arr[a][last] = arr[a][last].substring(0, arr[a][last].length - 1).replace(/""/g, '"');
  43. }
  44. }
  45. else {
  46. if (c === cLen - 1 && rows[r][c].indexOf('"') === 0 && (countQuotes(rows[r][c]) & 1)) {
  47. arr[a].push(rows[r][c].substring(1).replace(/""/g, '"'));
  48. multiline = true;
  49. }
  50. else {
  51. arr[a].push(rows[r][c].replace(/""/g, '"'));
  52. multiline = false;
  53. }
  54. }
  55. }
  56. if (!multiline) {
  57. a += 1;
  58. }
  59. }
  60. return arr;
  61. },
  62. /**
  63. * Encode array into valid spreadsheet string
  64. *
  65. * @param arr
  66. * @returns {String}
  67. */
  68. stringify: function (arr) {
  69. var r, rLen, c, cLen, str = '', val;
  70. for (r = 0, rLen = arr.length; r < rLen; r += 1) {
  71. cLen = arr[r].length;
  72. for (c = 0; c < cLen; c += 1) {
  73. if (c > 0) {
  74. str += '\t';
  75. }
  76. val = arr[r][c];
  77. if (typeof val === 'string') {
  78. if (val.indexOf('\n') > -1) {
  79. str += '"' + val.replace(/"/g, '""') + '"';
  80. }
  81. else {
  82. str += val;
  83. }
  84. }
  85. else if (val === null || val === void 0) { // void 0 resolves to undefined
  86. str += '';
  87. }
  88. else {
  89. str += val;
  90. }
  91. }
  92. if (r !== rLen - 1) {
  93. str += '\n';
  94. }
  95. }
  96. return str;
  97. }
  98. };
  99. if (typeof exports !== 'undefined') {
  100. exports.parse = SheetClip.parse;
  101. exports.stringify = SheetClip.stringify;
  102. } else {
  103. global.SheetClip = SheetClip;
  104. }
  105. }(window));