wsemi 1.8.72 → 1.8.73

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (508) hide show
  1. package/README.md +1 -9
  2. package/dist/wsemi.umd.js +6 -6
  3. package/dist/wsemi.umd.js.map +1 -1
  4. package/docs/-_class.mjs.html +1 -1
  5. package/docs/ab2blob.mjs.html +1 -1
  6. package/docs/ab2u8arr.mjs.html +1 -1
  7. package/docs/addExcelWorksheetFromData.mjs.html +68 -102
  8. package/docs/addMonth.mjs.html +1 -1
  9. package/docs/aes2str.mjs.html +1 -1
  10. package/docs/alive.mjs.html +1 -1
  11. package/docs/arr2dt.mjs.html +1 -1
  12. package/docs/arrAccum.mjs.html +1 -1
  13. package/docs/arrAdd.mjs.html +1 -1
  14. package/docs/arrAt.mjs.html +1 -1
  15. package/docs/arrDiff.mjs.html +1 -1
  16. package/docs/arrFilterByKeywords.mjs.html +1 -1
  17. package/docs/arrFilterByNum.mjs.html +1 -1
  18. package/docs/arrFilterByPnum.mjs.html +1 -1
  19. package/docs/arrFilterByPnumAndToLog.mjs.html +1 -1
  20. package/docs/arrFind.mjs.html +1 -1
  21. package/docs/arrGroupByMaxmin.mjs.html +1 -1
  22. package/docs/arrHas.mjs.html +1 -1
  23. package/docs/arrInsert.mjs.html +1 -1
  24. package/docs/arrLookupByMaxmin.mjs.html +1 -1
  25. package/docs/arrMax.mjs.html +1 -1
  26. package/docs/arrMin.mjs.html +1 -1
  27. package/docs/arrMulti.mjs.html +1 -1
  28. package/docs/arrNorm.mjs.html +1 -1
  29. package/docs/arrProduct.mjs.html +1 -1
  30. package/docs/arrPull.mjs.html +1 -1
  31. package/docs/arrPullAt.mjs.html +1 -1
  32. package/docs/arrReduce.mjs.html +1 -1
  33. package/docs/arrReverse.mjs.html +1 -1
  34. package/docs/arrSep.mjs.html +1 -1
  35. package/docs/arrSort.mjs.html +1 -1
  36. package/docs/asind.mjs.html +1 -1
  37. package/docs/atan2d.mjs.html +1 -1
  38. package/docs/atand.mjs.html +1 -1
  39. package/docs/attstr.mjs.html +1 -1
  40. package/docs/b642obj.mjs.html +1 -1
  41. package/docs/b642str.mjs.html +1 -1
  42. package/docs/b642u16arr.mjs.html +1 -1
  43. package/docs/b642u8arr.mjs.html +1 -1
  44. package/docs/binstr.mjs.html +1 -1
  45. package/docs/blob2ab.mjs.html +1 -1
  46. package/docs/blob2b64.mjs.html +1 -1
  47. package/docs/blob2str.mjs.html +1 -1
  48. package/docs/blob2u8arr.mjs.html +1 -1
  49. package/docs/blobs2b64s.mjs.html +1 -1
  50. package/docs/blobs2u8arrs.mjs.html +1 -1
  51. package/docs/bodyLog.mjs.html +1 -1
  52. package/docs/browserView.mjs.html +1 -1
  53. package/docs/browserViewFromBlob.mjs.html +1 -1
  54. package/docs/browserViewFromText.mjs.html +1 -1
  55. package/docs/browserViewFromU8arr.mjs.html +1 -1
  56. package/docs/bs2u8arr.mjs.html +1 -1
  57. package/docs/bufRead.mjs.html +1 -1
  58. package/docs/bufReadDbl.mjs.html +1 -1
  59. package/docs/bufWrite.mjs.html +1 -1
  60. package/docs/bufWriteDbl.mjs.html +1 -1
  61. package/docs/cache.mjs.html +1 -1
  62. package/docs/cacheBd.mjs.html +1 -1
  63. package/docs/cacheSt.mjs.html +1 -1
  64. package/docs/cbol.mjs.html +1 -1
  65. package/docs/cdbl.mjs.html +1 -1
  66. package/docs/ceil.mjs.html +1 -1
  67. package/docs/cfilesize.mjs.html +1 -1
  68. package/docs/cfinancial.mjs.html +1 -1
  69. package/docs/cint.mjs.html +1 -1
  70. package/docs/clearXSS.mjs.html +1 -1
  71. package/docs/clearXSSDyn.mjs.html +1 -1
  72. package/docs/color.mjs.html +1 -1
  73. package/docs/composeToTree.mjs.html +1 -1
  74. package/docs/convertToTree.mjs.html +1 -1
  75. package/docs/copyStrToClipboard.mjs.html +1 -1
  76. package/docs/cosd.mjs.html +1 -1
  77. package/docs/cotd.mjs.html +1 -1
  78. package/docs/createExcelWorkbook.mjs.html +28 -33
  79. package/docs/cscd.mjs.html +1 -1
  80. package/docs/cstr.mjs.html +1 -1
  81. package/docs/day2cht.mjs.html +1 -1
  82. package/docs/debounce.mjs.html +1 -1
  83. package/docs/delay.mjs.html +1 -1
  84. package/docs/dig.mjs.html +1 -1
  85. package/docs/digExp.mjs.html +1 -1
  86. package/docs/domAlert.mjs.html +1 -1
  87. package/docs/domAppend.mjs.html +1 -1
  88. package/docs/domCancelEvent.mjs.html +1 -1
  89. package/docs/domCompareText.mjs.html +1 -1
  90. package/docs/domConvertToPic.mjs.html +1 -1
  91. package/docs/domConvertToPicDyn.mjs.html +1 -1
  92. package/docs/domDetect.mjs.html +1 -1
  93. package/docs/domDrag.mjs.html +1 -1
  94. package/docs/domDragBarAndScroll.mjs.html +1 -1
  95. package/docs/domDragPreview.mjs.html +1 -1
  96. package/docs/domDropFiles.mjs.html +1 -1
  97. package/docs/domElementsFromPoint.mjs.html +1 -1
  98. package/docs/domFadeIn.mjs.html +1 -1
  99. package/docs/domFadeOut.mjs.html +1 -1
  100. package/docs/domFind.mjs.html +1 -1
  101. package/docs/domFinds.mjs.html +1 -1
  102. package/docs/domGetAttr.mjs.html +1 -1
  103. package/docs/domGetBoudRect.mjs.html +1 -1
  104. package/docs/domGetBoudRectRefSelf.mjs.html +1 -1
  105. package/docs/domGetFileAccept.mjs.html +1 -1
  106. package/docs/domGetFiles.mjs.html +1 -1
  107. package/docs/domGetParents.mjs.html +1 -1
  108. package/docs/domGetPointFromEvent.mjs.html +1 -1
  109. package/docs/domGetScrollableParent.mjs.html +1 -1
  110. package/docs/domGetWindowSize.mjs.html +1 -1
  111. package/docs/domIsClientXYIn.mjs.html +1 -1
  112. package/docs/domIsFocused.mjs.html +1 -1
  113. package/docs/domIsStable.mjs.html +1 -1
  114. package/docs/domIsVisible.mjs.html +1 -1
  115. package/docs/domPrepend.mjs.html +1 -1
  116. package/docs/domRemove.mjs.html +1 -1
  117. package/docs/domRenderMarkdownMind.mjs.html +1 -1
  118. package/docs/domRenderMarkdownMindDyn.mjs.html +1 -1
  119. package/docs/domRipple.mjs.html +1 -1
  120. package/docs/domScrollIntoView.mjs.html +1 -1
  121. package/docs/domScrollTo.mjs.html +1 -1
  122. package/docs/domSetAttr.mjs.html +1 -1
  123. package/docs/domShowImages.mjs.html +1 -1
  124. package/docs/domShowImagesDyn.mjs.html +1 -1
  125. package/docs/domShowInputAndGetFiles.mjs.html +21 -5
  126. package/docs/domShowInputAndGetFilesU8Arrs.mjs.html +1 -1
  127. package/docs/domShowInputDatatime.mjs.html +1 -1
  128. package/docs/domTooltip.mjs.html +1 -1
  129. package/docs/domTriggerEvent.mjs.html +1 -1
  130. package/docs/domVirtualCreate.mjs.html +1 -1
  131. package/docs/domVirtualCreateQueue.mjs.html +1 -1
  132. package/docs/downloadExcelFileFromData.mjs.html +109 -117
  133. package/docs/downloadExcelFileFromDataDyn.mjs.html +50 -59
  134. package/docs/downloadFileFromB64.mjs.html +1 -1
  135. package/docs/downloadFileFromBlob.mjs.html +1 -1
  136. package/docs/downloadFileFromText.mjs.html +1 -1
  137. package/docs/downloadFileFromU8Arr.mjs.html +1 -1
  138. package/docs/dtmapping.mjs.html +1 -1
  139. package/docs/dtpick.mjs.html +1 -1
  140. package/docs/estimateTicks.mjs.html +1 -1
  141. package/docs/evem.mjs.html +1 -1
  142. package/docs/examples/ex-blob2b64.html +1 -1
  143. package/docs/examples/ex-clearXSS.html +1 -1
  144. package/docs/examples/ex-clearXSSDyn.html +1 -1
  145. package/docs/examples/ex-colorConverter.html +1 -1
  146. package/docs/examples/ex-domCompareText.html +1 -1
  147. package/docs/examples/ex-domConvertToPic.html +1 -1
  148. package/docs/examples/ex-domDrag.html +1 -1
  149. package/docs/examples/ex-domDropFiles.html +1 -1
  150. package/docs/examples/ex-domIsVisible.html +1 -1
  151. package/docs/examples/ex-domRenderMarkdownMind.html +1 -1
  152. package/docs/examples/ex-domRenderMarkdownMindDyn.html +1 -1
  153. package/docs/examples/ex-domRipple.html +1 -1
  154. package/docs/examples/ex-domScrollIntoView.html +1 -1
  155. package/docs/examples/ex-domScrollTo.html +1 -1
  156. package/docs/examples/ex-domShowImages.html +1 -1
  157. package/docs/examples/ex-domShowImagesDyn.html +1 -1
  158. package/docs/examples/ex-domShowInputAndGetFiles.html +1 -1
  159. package/docs/examples/ex-domTooltip.html +1 -1
  160. package/docs/examples/ex-getFileHash.html +1 -1
  161. package/docs/examples/ex-getUserAgent.html +1 -1
  162. package/docs/examples/ex-getUserAgentDyn.html +1 -1
  163. package/docs/examples/ex-html2str.html +1 -1
  164. package/docs/examples/ex-obj2u8arr-u8arr2obj.html +1 -1
  165. package/docs/examples/ex-openLink.html +1 -1
  166. package/docs/examples/ex-str2aes-aes2str.html +1 -1
  167. package/docs/examples/ex-str2b64-b642str.html +1 -1
  168. package/docs/examples/ex-strFindFuzz.html +1 -1
  169. package/docs/examples/ex-timeTZ2expire-timeTZ2past.html +1 -1
  170. package/docs/examples/ex-xlsx.html +36 -36
  171. package/docs/execCli.mjs.html +1 -1
  172. package/docs/execJsCode.mjs.html +1 -1
  173. package/docs/execProcess.mjs.html +1 -1
  174. package/docs/execProcessKillPid.mjs.html +1 -1
  175. package/docs/filepathToTree.mjs.html +1 -1
  176. package/docs/files2data.mjs.html +1 -1
  177. package/docs/flattenToConn.mjs.html +1 -1
  178. package/docs/flattenTree.mjs.html +1 -1
  179. package/docs/floor.mjs.html +1 -1
  180. package/docs/fsBuildReadStreamText.mjs.html +1 -1
  181. package/docs/fsBuildWriteStreamText.mjs.html +1 -1
  182. package/docs/fsCleanFolder.mjs.html +1 -1
  183. package/docs/fsCleanFolderCore.mjs.html +1 -1
  184. package/docs/fsCopyFile.mjs.html +1 -1
  185. package/docs/fsCopyFileCore.mjs.html +1 -1
  186. package/docs/fsCopyFolder.mjs.html +1 -1
  187. package/docs/fsCopyFolderCore.mjs.html +1 -1
  188. package/docs/fsCreateFile.mjs.html +1 -1
  189. package/docs/fsCreateFileCore.mjs.html +1 -1
  190. package/docs/fsCreateFolder.mjs.html +1 -1
  191. package/docs/fsCreateFolderCore.mjs.html +1 -1
  192. package/docs/fsDeleteFile.mjs.html +1 -1
  193. package/docs/fsDeleteFileCore.mjs.html +1 -1
  194. package/docs/fsDeleteFileSafe.mjs.html +1 -1
  195. package/docs/fsDeleteFileSafeCore.mjs.html +1 -1
  196. package/docs/fsDeleteFolder.mjs.html +1 -1
  197. package/docs/fsDeleteFolderCore.mjs.html +1 -1
  198. package/docs/fsDeleteFolderSafe.mjs.html +1 -1
  199. package/docs/fsDeleteFolderSafeCore.mjs.html +1 -1
  200. package/docs/fsDownloadFile.mjs.html +1 -1
  201. package/docs/fsDownloadFileCore.mjs.html +1 -1
  202. package/docs/fsEvem.mjs.html +1 -1
  203. package/docs/fsExists.mjs.html +1 -1
  204. package/docs/fsExistsCore.mjs.html +1 -1
  205. package/docs/fsGetFileBasicHash.mjs.html +1 -1
  206. package/docs/fsGetFileBasicHashCore.mjs.html +1 -1
  207. package/docs/fsGetFileHash.mjs.html +1 -1
  208. package/docs/fsGetFileHashCore.mjs.html +1 -1
  209. package/docs/fsGetFileXxHash.mjs.html +1 -1
  210. package/docs/fsGetFileXxHashCore.mjs.html +1 -1
  211. package/docs/fsGetFilesInFolder.mjs.html +1 -1
  212. package/docs/fsGetFilesInFolderCore.mjs.html +1 -1
  213. package/docs/fsGetFilesWithHashInFolder.mjs.html +1 -1
  214. package/docs/fsGetFilesWithHashInFolderCore.mjs.html +1 -1
  215. package/docs/fsGetFolderBasicHash.mjs.html +1 -1
  216. package/docs/fsGetFolderBasicHashCore.mjs.html +1 -1
  217. package/docs/fsGetFoldersInFolder.mjs.html +1 -1
  218. package/docs/fsGetFoldersInFolderCore.mjs.html +1 -1
  219. package/docs/fsIsFile.mjs.html +1 -1
  220. package/docs/fsIsFileCore.mjs.html +1 -1
  221. package/docs/fsIsFolder.mjs.html +1 -1
  222. package/docs/fsIsFolderCore.mjs.html +1 -1
  223. package/docs/fsMergeFiles.mjs.html +1 -1
  224. package/docs/fsMergeFilesCore.mjs.html +1 -1
  225. package/docs/fsReadJson.mjs.html +1 -1
  226. package/docs/fsReadText.mjs.html +1 -1
  227. package/docs/fsReadTextCore.mjs.html +1 -1
  228. package/docs/fsRenameFile.mjs.html +1 -1
  229. package/docs/fsRenameFileCore.mjs.html +1 -1
  230. package/docs/fsRenameFolder.mjs.html +1 -1
  231. package/docs/fsRenameFolderCore.mjs.html +1 -1
  232. package/docs/fsSrlog.mjs.html +1 -1
  233. package/docs/fsSyncFolder.mjs.html +1 -1
  234. package/docs/fsSyncFolderCore.mjs.html +1 -1
  235. package/docs/fsTask.mjs.html +1 -1
  236. package/docs/fsTaskCp.mjs.html +1 -1
  237. package/docs/fsTreeFolder.mjs.html +1 -1
  238. package/docs/fsTreeFolderCore.mjs.html +1 -1
  239. package/docs/fsTreeFolderWithHash.mjs.html +1 -1
  240. package/docs/fsTreeFolderWithHashCore.mjs.html +1 -1
  241. package/docs/fsWatchFile.mjs.html +1 -1
  242. package/docs/fsWatchFolder.mjs.html +1 -1
  243. package/docs/fsWriteJson.mjs.html +1 -1
  244. package/docs/fsWriteText.mjs.html +1 -1
  245. package/docs/fsWriteTextCore.mjs.html +1 -1
  246. package/docs/genGradientColor.mjs.html +1 -1
  247. package/docs/genID.mjs.html +1 -1
  248. package/docs/genIDSeq.mjs.html +1 -1
  249. package/docs/genPm.mjs.html +1 -1
  250. package/docs/getBufferSize.mjs.html +1 -1
  251. package/docs/getClearPathName.mjs.html +1 -1
  252. package/docs/getCsvStrFromData.mjs.html +1 -1
  253. package/docs/getDataFromExcelFileU8Arr.mjs.html +223 -196
  254. package/docs/getDataFromExcelFileU8ArrDyn.mjs.html +38 -47
  255. package/docs/getEnv.mjs.html +1 -1
  256. package/docs/getErrorMessage.mjs.html +1 -1
  257. package/docs/getExcelU8ArrFromData.mjs.html +81 -78
  258. package/docs/getExcelU8ArrFromWorkbook.mjs.html +72 -81
  259. package/docs/getExcelWorkbookFromData.mjs.html +70 -99
  260. package/docs/getExcelWorkbookFromWorksheet.mjs.html +64 -95
  261. package/docs/getExcelWorksheetFromData.mjs.html +81 -110
  262. package/docs/getFileAccept.mjs.html +1 -1
  263. package/docs/getFileBasicHash.mjs.html +1 -1
  264. package/docs/getFileHash.mjs.html +1 -1
  265. package/docs/getFileName.mjs.html +1 -1
  266. package/docs/getFileNameExt.mjs.html +1 -1
  267. package/docs/getFileTrueName.mjs.html +1 -1
  268. package/docs/getFileType.mjs.html +1 -1
  269. package/docs/getFileXxHash.mjs.html +1 -1
  270. package/docs/getGlobal.mjs.html +1 -1
  271. package/docs/getObjSize.mjs.html +1 -1
  272. package/docs/getPathParent.mjs.html +1 -1
  273. package/docs/getTimeBetween.mjs.html +1 -1
  274. package/docs/getTimeFromUnit.mjs.html +1 -1
  275. package/docs/getTimeHp.mjs.html +1 -1
  276. package/docs/getTimeObject.mjs.html +1 -1
  277. package/docs/getTimeRange.mjs.html +1 -1
  278. package/docs/getUserAgent.mjs.html +1 -1
  279. package/docs/getUserAgentDyn.mjs.html +1 -1
  280. package/docs/getltdtkeys.mjs.html +1 -1
  281. package/docs/global.html +1 -1
  282. package/docs/haskey.mjs.html +1 -1
  283. package/docs/html2str.mjs.html +1 -1
  284. package/docs/htmlDecode.mjs.html +1 -1
  285. package/docs/htmlEncode.mjs.html +1 -1
  286. package/docs/importResources.mjs.html +1 -1
  287. package/docs/index.html +1 -1
  288. package/docs/interp1.mjs.html +1 -1
  289. package/docs/isDate.mjs.html +1 -1
  290. package/docs/isDev.mjs.html +1 -1
  291. package/docs/isEle.mjs.html +1 -1
  292. package/docs/isEleExistByID.mjs.html +1 -1
  293. package/docs/isEmail.mjs.html +1 -1
  294. package/docs/isErr.mjs.html +1 -1
  295. package/docs/isIE.mjs.html +1 -1
  296. package/docs/isNarrow.mjs.html +1 -1
  297. package/docs/isStrHasCapital.mjs.html +1 -1
  298. package/docs/isStrHasLetter.mjs.html +1 -1
  299. package/docs/isStrHasLowerCase.mjs.html +1 -1
  300. package/docs/isStrHasNumber.mjs.html +1 -1
  301. package/docs/isStrHasSpace.mjs.html +1 -1
  302. package/docs/isStrHasSymbol.mjs.html +1 -1
  303. package/docs/isUserIdentify.mjs.html +1 -1
  304. package/docs/isUserName.mjs.html +1 -1
  305. package/docs/isUserPw.mjs.html +1 -1
  306. package/docs/isWindow.mjs.html +1 -1
  307. package/docs/isab.mjs.html +1 -1
  308. package/docs/isarr.mjs.html +1 -1
  309. package/docs/isarr0.mjs.html +1 -1
  310. package/docs/isbigint.mjs.html +1 -1
  311. package/docs/isblob.mjs.html +1 -1
  312. package/docs/isbol.mjs.html +1 -1
  313. package/docs/isday.mjs.html +1 -1
  314. package/docs/isearr.mjs.html +1 -1
  315. package/docs/iseobj.mjs.html +1 -1
  316. package/docs/iser.mjs.html +1 -1
  317. package/docs/isernot.mjs.html +1 -1
  318. package/docs/isestr.mjs.html +1 -1
  319. package/docs/isfile.mjs.html +1 -1
  320. package/docs/isfun.mjs.html +1 -1
  321. package/docs/isint.mjs.html +1 -1
  322. package/docs/ismonth.mjs.html +1 -1
  323. package/docs/isn0int.mjs.html +1 -1
  324. package/docs/isn0num.mjs.html +1 -1
  325. package/docs/isnan.mjs.html +1 -1
  326. package/docs/isnbr.mjs.html +1 -1
  327. package/docs/isnint.mjs.html +1 -1
  328. package/docs/isnnum.mjs.html +1 -1
  329. package/docs/isnull.mjs.html +1 -1
  330. package/docs/isnum.mjs.html +1 -1
  331. package/docs/isobj.mjs.html +1 -1
  332. package/docs/isobj0.mjs.html +1 -1
  333. package/docs/isp0int.mjs.html +1 -1
  334. package/docs/isp0num.mjs.html +1 -1
  335. package/docs/ispint.mjs.html +1 -1
  336. package/docs/ispm.mjs.html +1 -1
  337. package/docs/ispnum.mjs.html +1 -1
  338. package/docs/isstr.mjs.html +1 -1
  339. package/docs/isstr0.mjs.html +1 -1
  340. package/docs/istime.mjs.html +1 -1
  341. package/docs/istimeTZ.mjs.html +1 -1
  342. package/docs/istimems.mjs.html +1 -1
  343. package/docs/istimemsTZ.mjs.html +1 -1
  344. package/docs/isu16arr.mjs.html +1 -1
  345. package/docs/isu8arr.mjs.html +1 -1
  346. package/docs/isundefined.mjs.html +1 -1
  347. package/docs/j2o.mjs.html +1 -1
  348. package/docs/judge.mjs.html +1 -1
  349. package/docs/keysmat2ltdt.mjs.html +1 -1
  350. package/docs/ltdt2vrtsable.mjs.html +1 -1
  351. package/docs/ltdtDiff.mjs.html +1 -1
  352. package/docs/ltdtDiffByKey.mjs.html +1 -1
  353. package/docs/ltdtkeys2mat.mjs.html +1 -1
  354. package/docs/ltdtkeysheads2mat.mjs.html +1 -1
  355. package/docs/ltdtmapping.mjs.html +1 -1
  356. package/docs/ltdtmerge.mjs.html +1 -1
  357. package/docs/ltdtpick.mjs.html +1 -1
  358. package/docs/ltdtpull.mjs.html +1 -1
  359. package/docs/mat2ltdt.mjs.html +1 -1
  360. package/docs/matConcat.mjs.html +1 -1
  361. package/docs/matDiff.mjs.html +1 -1
  362. package/docs/matat.mjs.html +1 -1
  363. package/docs/now2str.mjs.html +1 -1
  364. package/docs/now2strp.mjs.html +1 -1
  365. package/docs/nowDay2str.mjs.html +1 -1
  366. package/docs/nowms2str.mjs.html +1 -1
  367. package/docs/nowms2strp.mjs.html +1 -1
  368. package/docs/o2j.mjs.html +1 -1
  369. package/docs/obj2b64.mjs.html +1 -1
  370. package/docs/obj2pb64.mjs.html +1 -1
  371. package/docs/obj2str.mjs.html +1 -1
  372. package/docs/obj2stru8arr.mjs.html +1 -1
  373. package/docs/obj2u8arr.mjs.html +1 -1
  374. package/docs/objSortBy.mjs.html +1 -1
  375. package/docs/objSortByKeys.mjs.html +1 -1
  376. package/docs/oo.mjs.html +1 -1
  377. package/docs/openLink.mjs.html +1 -1
  378. package/docs/pb642obj.mjs.html +1 -1
  379. package/docs/pmChain.mjs.html +1 -1
  380. package/docs/pmConvertResolve.mjs.html +1 -1
  381. package/docs/pmDebounce.mjs.html +1 -1
  382. package/docs/pmHook.mjs.html +1 -1
  383. package/docs/pmHookReject.mjs.html +1 -1
  384. package/docs/pmIni.mjs.html +1 -1
  385. package/docs/pmInvResolve.mjs.html +1 -1
  386. package/docs/pmKeyMutex.mjs.html +1 -1
  387. package/docs/pmMap.mjs.html +1 -1
  388. package/docs/pmQueue.mjs.html +1 -1
  389. package/docs/pmSeries.mjs.html +1 -1
  390. package/docs/pmThrottle.mjs.html +1 -1
  391. package/docs/pmTimeout.mjs.html +6 -4
  392. package/docs/preciseNum.mjs.html +1 -1
  393. package/docs/pseudoRandom.mjs.html +1 -1
  394. package/docs/pseudoRandomIntRange.mjs.html +1 -1
  395. package/docs/pseudoRandomIntsNdpRange.mjs.html +1 -1
  396. package/docs/pseudoRandomIntsRange.mjs.html +1 -1
  397. package/docs/pseudoRandomRange.mjs.html +1 -1
  398. package/docs/pseudoRandomsRange.mjs.html +1 -1
  399. package/docs/queue.mjs.html +1 -1
  400. package/docs/random.mjs.html +1 -1
  401. package/docs/randomIntRange.mjs.html +1 -1
  402. package/docs/randomIntsNdpRange.mjs.html +1 -1
  403. package/docs/randomIntsRange.mjs.html +1 -1
  404. package/docs/randomRange.mjs.html +1 -1
  405. package/docs/randomsRange.mjs.html +1 -1
  406. package/docs/rang.mjs.html +1 -1
  407. package/docs/rep.mjs.html +1 -1
  408. package/docs/repObj.mjs.html +1 -1
  409. package/docs/replace.mjs.html +1 -1
  410. package/docs/replaceObj.mjs.html +1 -1
  411. package/docs/replacePlus.mjs.html +1 -1
  412. package/docs/round.mjs.html +1 -1
  413. package/docs/secd.mjs.html +1 -1
  414. package/docs/sep.mjs.html +1 -1
  415. package/docs/sepInt.mjs.html +1 -1
  416. package/docs/setIntervalHp.mjs.html +1 -1
  417. package/docs/setTimeoutHp.mjs.html +1 -1
  418. package/docs/sind.mjs.html +1 -1
  419. package/docs/split.mjs.html +1 -1
  420. package/docs/str2aes.mjs.html +1 -1
  421. package/docs/str2b64.mjs.html +1 -1
  422. package/docs/str2hint.mjs.html +1 -1
  423. package/docs/str2md5.mjs.html +1 -1
  424. package/docs/str2obj.mjs.html +1 -1
  425. package/docs/str2sha.mjs.html +1 -1
  426. package/docs/str2sha512.mjs.html +1 -1
  427. package/docs/str2u8arr.mjs.html +1 -1
  428. package/docs/strCompare.mjs.html +1 -1
  429. package/docs/strDiff.mjs.html +1 -1
  430. package/docs/strDiffToHtml.mjs.html +1 -1
  431. package/docs/strFindFuzz.mjs.html +1 -1
  432. package/docs/strFindSimilar.mjs.html +1 -1
  433. package/docs/strTruncate.mjs.html +1 -1
  434. package/docs/strdelleft.mjs.html +1 -1
  435. package/docs/strdelright.mjs.html +1 -1
  436. package/docs/strleft.mjs.html +1 -1
  437. package/docs/strmid.mjs.html +1 -1
  438. package/docs/strright.mjs.html +1 -1
  439. package/docs/stru8arr2obj.mjs.html +1 -1
  440. package/docs/tand.mjs.html +1 -1
  441. package/docs/time2day.mjs.html +1 -1
  442. package/docs/time2hour.mjs.html +1 -1
  443. package/docs/time2min.mjs.html +1 -1
  444. package/docs/timeTZ2day.mjs.html +1 -1
  445. package/docs/timeTZ2expire.mjs.html +1 -1
  446. package/docs/timeTZ2hour.mjs.html +1 -1
  447. package/docs/timeTZ2min.mjs.html +1 -1
  448. package/docs/timeTZ2past.mjs.html +1 -1
  449. package/docs/timems2day.mjs.html +1 -1
  450. package/docs/timems2hour.mjs.html +1 -1
  451. package/docs/timems2min.mjs.html +1 -1
  452. package/docs/timems2time.mjs.html +1 -1
  453. package/docs/timemsTZ2day.mjs.html +1 -1
  454. package/docs/timemsTZ2expire.mjs.html +1 -1
  455. package/docs/timemsTZ2hour.mjs.html +1 -1
  456. package/docs/timemsTZ2min.mjs.html +1 -1
  457. package/docs/timemsTZ2past.mjs.html +1 -1
  458. package/docs/timemsTZ2time.mjs.html +1 -1
  459. package/docs/treeObj.mjs.html +1 -1
  460. package/docs/treeToFilepath.mjs.html +1 -1
  461. package/docs/trim.mjs.html +1 -1
  462. package/docs/u16arr2b64.mjs.html +1 -1
  463. package/docs/u16arr2u8arr.mjs.html +1 -1
  464. package/docs/u8arr2ab.mjs.html +1 -1
  465. package/docs/u8arr2b64.mjs.html +1 -1
  466. package/docs/u8arr2blob.mjs.html +1 -1
  467. package/docs/u8arr2bs.mjs.html +1 -1
  468. package/docs/u8arr2obj.mjs.html +1 -1
  469. package/docs/u8arr2str.mjs.html +1 -1
  470. package/docs/u8arr2u16arr.mjs.html +1 -1
  471. package/docs/urlParse.mjs.html +1 -1
  472. package/docs/verifyValue.mjs.html +1 -1
  473. package/docs/waitFun.mjs.html +1 -1
  474. package/docs/wsemi.html +169 -255
  475. package/examples/ex-xlsx.html +35 -35
  476. package/package.json +3 -3
  477. package/src/addExcelWorksheetFromData.mjs +67 -101
  478. package/src/createExcelWorkbook.mjs +27 -32
  479. package/src/domShowInputAndGetFiles.mjs +20 -4
  480. package/src/downloadExcelFileFromData.mjs +108 -116
  481. package/src/downloadExcelFileFromDataDyn.mjs +49 -58
  482. package/src/getDataFromExcelFileU8Arr.mjs +222 -195
  483. package/src/getDataFromExcelFileU8ArrDyn.mjs +37 -46
  484. package/src/getExcelU8ArrFromData.mjs +80 -77
  485. package/src/getExcelU8ArrFromWorkbook.mjs +70 -79
  486. package/src/getExcelWorkbookFromData.mjs +69 -98
  487. package/src/getExcelWorkbookFromWorksheet.mjs +63 -94
  488. package/src/getExcelWorksheetFromData.mjs +80 -109
  489. package/src/pmTimeout.mjs +5 -3
  490. package/test/addExcelWorksheetFromData.test.mjs +60 -62
  491. package/test/createExcelWorkbook.test.mjs +19 -19
  492. package/test/downloadExcelFileFromData.test.mjs +53 -11
  493. package/test/downloadExcelFileFromDataDyn.test.mjs +43 -11
  494. package/test/getDataFromExcelFileU8Arr.test.mjs +46 -12
  495. package/test/getDataFromExcelFileU8ArrDyn.test.mjs +33 -11
  496. package/test/getExcelU8ArrFromData.test.mjs +76 -20
  497. package/test/getExcelU8ArrFromWorkbook.test.mjs +53 -37
  498. package/test/getExcelWorkbookFromData.test.mjs +32 -28
  499. package/test/getExcelWorkbookFromWorksheet.test.mjs +33 -31
  500. package/test/getExcelWorksheetFromData.test.mjs +59 -63
  501. package/test/pmTimeout.test.mjs +64 -12
  502. package/toolfp/dist/wsemip.umd.js +1 -1
  503. package/toolg/gDistRollup.mjs +2 -2
  504. package/toolparfor/dist/wpf.umd.js +1 -1
  505. package/toolparfor/dist/wpf_pmSeries.umd.js +1 -1
  506. package/docs/examples/ex-xlsxDyn.html +0 -137
  507. package/examples/ex-xlsxDyn.html +0 -137
  508. package/src/_getXLSX.mjs +0 -49
@@ -1,110 +1,81 @@
1
1
  import every from 'lodash-es/every.js'
2
- import isarr from './isarr.mjs'
3
- import iseobj from './iseobj.mjs'
4
- import isEle from './isEle.mjs'
5
- import ltdtkeysheads2mat from './ltdtkeysheads2mat.mjs'
6
- import getXLSX from './_getXLSX.mjs'
7
-
8
-
9
- /**
10
- * 由數據陣列或DOM的table元素轉成為Excel的Worksheet物件
11
- *
12
- * Unit Test: {@link https://github.com/yuda-lyu/wsemi/blob/master/test/getExcelWorksheetFromData.test.mjs Github}
13
- * @memberOf wsemi
14
- * @param {Array|Element} data 輸入數據陣列或是DOM的table元素(Element)
15
- * @returns {Object} 回傳Excel的Worksheet物件
16
- * @example
17
- *
18
- * let mat = [
19
- * ['a', '123', 456],
20
- * [null, 'abc123', '', 111.222333],
21
- * ]
22
- *
23
- * let ws1 = getExcelWorksheetFromData(mat)
24
- * console.log('ws1', ws1)
25
- * // => ws1 {
26
- * // A1: { v: 'a', t: 's' },
27
- * // B1: { v: '123', t: 's' },
28
- * // C1: { v: 456, t: 'n' },
29
- * // B2: { v: 'abc123', t: 's' },
30
- * // C2: { v: '', t: 's' },
31
- * // D2: { v: 111.222333, t: 'n' },
32
- * // '!ref': 'A1:D2'
33
- * // }
34
- *
35
- * let ltdt = [
36
- * { x: 'a', y: '123', z: 456 },
37
- * { x: null, y: 'abc123', z: '', a: 111.222333 },
38
- * ]
39
- *
40
- * let ws2 = getExcelWorksheetFromData(ltdt)
41
- * console.log('ws2', ws2)
42
- * // => ws2 {
43
- * // A1: { v: 'x', t: 's' },
44
- * // B1: { v: 'y', t: 's' },
45
- * // C1: { v: 'z', t: 's' },
46
- * // D1: { v: 'a', t: 's' },
47
- * // A2: { v: 'a', t: 's' },
48
- * // B2: { v: '123', t: 's' },
49
- * // C2: { v: 456, t: 'n' },
50
- * // D2: { v: '', t: 's' },
51
- * // A3: { v: 'null', t: 's' },
52
- * // B3: { v: 'abc123', t: 's' },
53
- * // C3: { v: '', t: 's' },
54
- * // D3: { v: 111.222333, t: 'n' },
55
- * // '!ref': 'A1:D3'
56
- * // }
57
- *
58
- */
59
- function getExcelWorksheetFromData(data) {
60
-
61
- //check
62
- if (!isarr(data) && !isEle(data)) {
63
- return {
64
- error: 'data is not an array or element',
65
- }
66
- }
67
-
68
- //ws
69
- let ws = null
70
- try {
71
-
72
- //xlutls
73
- let xl = getXLSX()
74
- let xlutls = xl.utils
75
-
76
- if (isarr(data)) {
77
-
78
- //check ltdt
79
- let b = every(data, iseobj)
80
- if (b) {
81
- data = ltdtkeysheads2mat(data)
82
- }
83
-
84
- //ws
85
- ws = xlutls.aoa_to_sheet(data)
86
-
87
- }
88
- else if (isEle(data)) {
89
-
90
- //ws
91
- ws = xlutls.table_to_sheet(data, {
92
- raw: true,
93
- // cellDates: true,
94
- // dateNF: 0,
95
- })
96
-
97
- }
98
-
99
- }
100
- catch (err) {
101
- return {
102
- error: err
103
- }
104
- }
105
-
106
- return ws
107
- }
108
-
109
-
110
- export default getExcelWorksheetFromData
2
+ import isarr from './isarr.mjs'
3
+ import iseobj from './iseobj.mjs'
4
+ import ltdtkeysheads2mat from './ltdtkeysheads2mat.mjs'
5
+
6
+
7
+ /**
8
+ * 由數據陣列轉成為Excel的Worksheet物件
9
+ *
10
+ * Worksheet物件格式為{ rows },rows為二維值陣列,不含分頁名稱,名稱由getExcelWorkbookFromWorksheet或addExcelWorksheetFromData給予
11
+ * 數據陣列可為二維陣列(mat)或物件陣列(ltdt),ltdt會以各物件之鍵作為表頭自動轉為mat
12
+ *
13
+ * Unit Test: {@link https://github.com/yuda-lyu/wsemi/blob/master/test/getExcelWorksheetFromData.test.mjs Github}
14
+ * @memberOf wsemi
15
+ * @param {Array} data 輸入數據陣列,可為二維陣列(mat)或物件陣列(ltdt)
16
+ * @returns {Object} 回傳Excel的Worksheet物件,data非陣列時回傳{ error }物件
17
+ * @example
18
+ *
19
+ * let mat = [
20
+ * ['a', '123', 456],
21
+ * [null, 'abc123', '', 111.222333],
22
+ * ]
23
+ *
24
+ * let ws1 = getExcelWorksheetFromData(mat)
25
+ * console.log(ws1)
26
+ * // => {
27
+ * // rows: [ [ 'a', '123', 456 ], [ null, 'abc123', '', 111.222333 ] ]
28
+ * // }
29
+ *
30
+ * let ltdt = [
31
+ * { x: 'a', y: '123', z: 456 },
32
+ * { x: null, y: 'abc123', z: '', a: 111.222333 },
33
+ * ]
34
+ *
35
+ * let ws2 = getExcelWorksheetFromData(ltdt)
36
+ * console.log(ws2)
37
+ * // => {
38
+ * // rows: [
39
+ * // [ 'x', 'y', 'z', 'a' ],
40
+ * // [ 'a', '123', 456, '' ],
41
+ * // [ 'null', 'abc123', '', 111.222333 ]
42
+ * // ]
43
+ * // }
44
+ *
45
+ */
46
+ function getExcelWorksheetFromData(data) {
47
+
48
+ //check
49
+ if (!isarr(data)) {
50
+ return {
51
+ error: 'data is not an array',
52
+ }
53
+ }
54
+
55
+ //ws
56
+ let ws = null
57
+ try {
58
+
59
+ //check ltdt, 全元素皆為物件時視為ltdt, 以鍵作表頭轉mat
60
+ let b = every(data, iseobj)
61
+ if (b) {
62
+ data = ltdtkeysheads2mat(data)
63
+ }
64
+
65
+ //ws
66
+ ws = {
67
+ rows: data,
68
+ }
69
+
70
+ }
71
+ catch (err) {
72
+ return {
73
+ error: err
74
+ }
75
+ }
76
+
77
+ return ws
78
+ }
79
+
80
+
81
+ export default getExcelWorksheetFromData
package/src/pmTimeout.mjs CHANGED
@@ -11,11 +11,12 @@ import isp0int from './isp0int.mjs'
11
11
  * 以Promise.race令pm與計時器競速,pm先完成則原樣回傳其resolve或reject之結果,逾時則reject一個Error
12
12
  * 該Error之message為'timeout[ms數ms]'(有label時置於前綴),並帶有code為'TIMEOUT'與timeout為逾時毫秒數等欄位,供呼叫端辨別為逾時而非pm自身之錯誤
13
13
  * 注意JavaScript無法中止已啟動之Promise,逾時僅代表不再等待其結果,pm內之工作仍會繼續執行至自然結束,若需一併中止內部工作(如子進程)須由pm自行處理
14
+ * 本函數為async function,參數錯誤亦以reject傳出而非同步throw,故可與逾時錯誤一併由.catch或try/catch接住
14
15
  *
15
16
  * Unit Test: {@link https://github.com/yuda-lyu/wsemi/blob/master/test/pmTimeout.test.mjs Github}
16
17
  * @memberOf wsemi
17
- * @param {Promise} pm 輸入Promise物件,非Promise時擲出錯誤'invalid pm'
18
- * @param {Integer} ms 輸入逾時毫秒數,須為非負整數,為0代表下一輪事件迴圈即逾時,其餘擲出錯誤'invalid ms[ms數]'
18
+ * @param {Promise} pm 輸入Promise物件,非Promise時reject錯誤'invalid pm'
19
+ * @param {Integer} ms 輸入逾時毫秒數,須為非負整數,為0代表下一輪事件迴圈即逾時,其餘reject錯誤'invalid ms[ms數]'
19
20
  * @param {Object} [opt={}] 輸入設定物件
20
21
  * @param {String} [opt.label=''] 輸入識別字串,將置於逾時錯誤訊息之前綴以利辨識來源,非有效字串時回退為空字串,預設''
21
22
  * @returns {Promise} 回傳Promise,pm先完成則resolve或reject其結果,逾時則reject一個code為'TIMEOUT'之Error
@@ -65,7 +66,8 @@ import isp0int from './isp0int.mjs'
65
66
  */
66
67
  async function pmTimeout(pm, ms, opt = {}) {
67
68
 
68
- //check, pm與ms給錯視為程式撰寫錯誤而擲出錯誤
69
+ //check, pm與ms給錯視為程式撰寫錯誤
70
+ //本函數為async function, 故此處throw會轉為reject傳出, 與pm*家族之錯誤傳遞管道一致(見pmSeries/pmChain)
69
71
  if (!ispm(pm)) {
70
72
  throw new Error(`invalid pm`)
71
73
  }
@@ -1,63 +1,61 @@
1
- import assert from 'assert'
1
+ import assert from 'assert'
2
2
  import cloneDeep from 'lodash-es/cloneDeep.js'
3
- import createExcelWorkbook from '../src/createExcelWorkbook.mjs'
4
- import addExcelWorksheetFromData from '../src/addExcelWorksheetFromData.mjs'
5
-
6
-
7
- describe(`addExcelWorksheetFromData`, function() {
8
-
9
- let data = [
10
- ['a', '123', 456],
11
- [null, 'abc123', '', 111.222333],
12
- ]
13
-
14
- let wb = createExcelWorkbook()
15
- // console.log(wb)
16
- // => Workbook { SheetNames: [], Sheets: {} }
17
-
18
- let wbIn = cloneDeep(wb)
19
-
20
- let wbOut = {
21
- 'SheetNames': [
22
- 'tester'
23
- ],
24
- 'Sheets': {
25
- 'tester': {
26
- 'A1': {
27
- 'v': 'a',
28
- 't': 's'
29
- },
30
- 'B1': {
31
- 'v': '123',
32
- 't': 's'
33
- },
34
- 'C1': {
35
- 'v': 456,
36
- 't': 'n'
37
- },
38
- 'B2': {
39
- 'v': 'abc123',
40
- 't': 's'
41
- },
42
- 'C2': {
43
- 'v': '',
44
- 't': 's'
45
- },
46
- 'D2': {
47
- 'v': 111.222333,
48
- 't': 'n'
49
- },
50
- '!ref': 'A1:D2'
51
- }
52
- }
53
- }
54
-
55
- it(`should return ${JSON.stringify(wbOut)} when input ${JSON.stringify(wbIn)}, ${JSON.stringify(data)}, 'tester'`, function() {
56
- let r = addExcelWorksheetFromData(wb, data, 'tester')
57
- r = JSON.stringify(r)
58
- let rr = wbOut
59
- rr = JSON.stringify(rr)
60
- assert.strict.deepStrictEqual(r, rr)
61
- })
62
-
63
- })
3
+ import createExcelWorkbook from '../src/createExcelWorkbook.mjs'
4
+ import addExcelWorksheetFromData from '../src/addExcelWorksheetFromData.mjs'
5
+
6
+
7
+ describe(`addExcelWorksheetFromData`, function() {
8
+
9
+ let data = [
10
+ ['a', '123', 456],
11
+ [null, 'abc123', '', 111.222333],
12
+ ]
13
+
14
+ let wb = createExcelWorkbook()
15
+ // console.log(wb)
16
+ // => { sheets: [] }
17
+
18
+ let wbIn = cloneDeep(wb)
19
+
20
+ let wbOut = {
21
+ sheets: [
22
+ {
23
+ rows: [
24
+ ['a', '123', 456],
25
+ [null, 'abc123', '', 111.222333],
26
+ ],
27
+ name: 'tester',
28
+ },
29
+ ],
30
+ }
31
+
32
+ it(`should return ${JSON.stringify(wbOut)} when input ${JSON.stringify(wbIn)}, ${JSON.stringify(data)}, 'tester'`, function() {
33
+ let r = addExcelWorksheetFromData(wb, data, 'tester')
34
+ r = JSON.stringify(r)
35
+ let rr = wbOut
36
+ rr = JSON.stringify(rr)
37
+ assert.strict.deepStrictEqual(r, rr)
38
+ })
39
+
40
+ it(`should append multi sheets in order`, function() {
41
+ let wb2 = createExcelWorkbook()
42
+ addExcelWorksheetFromData(wb2, [['a1']], 's1')
43
+ addExcelWorksheetFromData(wb2, [['b1']], 's2')
44
+ assert.strict.deepStrictEqual(wb2.sheets.length, 2)
45
+ assert.strict.deepStrictEqual(wb2.sheets[0].name, 's1')
46
+ assert.strict.deepStrictEqual(wb2.sheets[1].name, 's2')
47
+ })
48
+
49
+ it(`should return error object when wb is invalid`, function() {
50
+ assert.strict.deepStrictEqual(addExcelWorksheetFromData(null, data).error, 'wb is not an effective object')
51
+ assert.strict.deepStrictEqual(addExcelWorksheetFromData({ a: 1 }, data).error, 'wb.sheets is not an array')
52
+ })
53
+
54
+ it(`should return error object when data is invalid`, function() {
55
+ let wb3 = createExcelWorkbook()
56
+ let r = addExcelWorksheetFromData(wb3, 'not-array', 's1')
57
+ assert.strict.deepStrictEqual(r.error, 'data is not an array')
58
+ assert.strict.deepStrictEqual(wb3.sheets.length, 0)
59
+ })
60
+
61
+ })
@@ -1,19 +1,19 @@
1
- import assert from 'assert'
2
- import createExcelWorkbook from '../src/createExcelWorkbook.mjs'
3
-
4
-
5
- describe(`createExcelWorkbook`, function() {
6
-
7
- // let wb = createExcelWorkbook()
8
- // console.log(wb)
9
- let wb = { SheetNames: [], Sheets: {} }
10
-
11
- it(`should return ${JSON.stringify(wb)} when input undefined`, function() {
12
- let r = createExcelWorkbook()
13
- r = JSON.stringify(r)
14
- let rr = wb
15
- rr = JSON.stringify(rr)
16
- assert.strict.deepStrictEqual(r, rr)
17
- })
18
-
19
- })
1
+ import assert from 'assert'
2
+ import createExcelWorkbook from '../src/createExcelWorkbook.mjs'
3
+
4
+
5
+ describe(`createExcelWorkbook`, function() {
6
+
7
+ // let wb = createExcelWorkbook()
8
+ // console.log(wb)
9
+ let wb = { sheets: [] }
10
+
11
+ it(`should return ${JSON.stringify(wb)} when input undefined`, function() {
12
+ let r = createExcelWorkbook()
13
+ r = JSON.stringify(r)
14
+ let rr = wb
15
+ rr = JSON.stringify(rr)
16
+ assert.strict.deepStrictEqual(r, rr)
17
+ })
18
+
19
+ })
@@ -1,11 +1,53 @@
1
- import assert from 'assert'
2
- //import downloadExcelFileFromData from '../src/downloadExcelFileFromData.mjs'
3
-
4
-
5
- describe(`downloadExcelFileFromData`, function() {
6
-
7
- it(`need test in browser`, function() {
8
- assert.strict.deepStrictEqual(1, 1)
9
- })
10
-
11
- })
1
+ import fs from 'fs'
2
+ import assert from 'assert'
3
+ import fsCreateFolder from '../src/fsCreateFolder.mjs'
4
+ import fsDeleteFolder from '../src/fsDeleteFolder.mjs'
5
+ import getDataFromExcelFileU8Arr from '../src/getDataFromExcelFileU8Arr.mjs'
6
+ import downloadExcelFileFromData from '../src/downloadExcelFileFromData.mjs'
7
+
8
+
9
+ //本檔測試一律以await呼叫: 對同步實作與async實作皆可通過, 供Excel引擎抽換時作為行為合約
10
+ //瀏覽器端下載路徑需於瀏覽器測試, 此處測試Node.js端寫檔路徑
11
+ describe(`downloadExcelFileFromData`, function() {
12
+
13
+ let fdt = './_test_downloadExcelFileFromData'
14
+
15
+ before(function() {
16
+ fsCreateFolder(fdt)
17
+ })
18
+
19
+ after(function() {
20
+ fsDeleteFolder(fdt)
21
+ })
22
+
23
+ it(`should write an xlsx file in nodejs and roundtrip mat data`, async function() {
24
+ let fp = `${fdt}/temp-mat.xlsx`
25
+ let data = [['x', 'y'], ['a', '123'], ['b', 456]]
26
+ await downloadExcelFileFromData(fp, 'mysheet', data)
27
+ assert.strict.deepStrictEqual(fs.existsSync(fp), true)
28
+ let u8a = fs.readFileSync(fp)
29
+ let r = await getDataFromExcelFileU8Arr(u8a, { fmt: 'array' })
30
+ assert.strict.deepStrictEqual(r[0].sheetname, 'mysheet')
31
+ assert.strict.deepStrictEqual(r[0].data, [['x', 'y'], ['a', '123'], ['b', '456']])
32
+ })
33
+
34
+ it(`should write an xlsx file in nodejs and roundtrip ltdt data`, async function() {
35
+ let fp = `${fdt}/temp-ltdt.xlsx`
36
+ let ltdt = [{ x: 'a', y: '中文' }, { x: 'b', y: 'abc' }]
37
+ await downloadExcelFileFromData(fp, 'data', ltdt)
38
+ let u8a = fs.readFileSync(fp)
39
+ let r = await getDataFromExcelFileU8Arr(u8a, { fmt: 'ltdt' })
40
+ assert.strict.deepStrictEqual(r[0].data, [{ x: 'a', y: '中文' }, { x: 'b', y: 'abc' }])
41
+ })
42
+
43
+ it(`should return error object when fileName is invalid`, async function() {
44
+ let r = await downloadExcelFileFromData('', 'data', [['a']])
45
+ assert.strict.deepStrictEqual(typeof r.error === 'string', true)
46
+ })
47
+
48
+ it(`should return error object when data is invalid`, async function() {
49
+ let r = await downloadExcelFileFromData(`${fdt}/x.xlsx`, 'data', 'not-valid')
50
+ assert.strict.deepStrictEqual(typeof r.error === 'string', true)
51
+ })
52
+
53
+ })
@@ -1,11 +1,43 @@
1
- import assert from 'assert'
2
- //import downloadExcelFileFromDataDyn from '../src/downloadExcelFileFromDataDyn.mjs'
3
-
4
-
5
- describe(`downloadExcelFileFromDataDyn`, function() {
6
-
7
- it(`need test in browser`, function() {
8
- assert.strict.deepStrictEqual(1, 1)
9
- })
10
-
11
- })
1
+ import fs from 'fs'
2
+ import assert from 'assert'
3
+ import fsCreateFolder from '../src/fsCreateFolder.mjs'
4
+ import fsDeleteFolder from '../src/fsDeleteFolder.mjs'
5
+ import getDataFromExcelFileU8Arr from '../src/getDataFromExcelFileU8Arr.mjs'
6
+ import downloadExcelFileFromDataDyn from '../src/downloadExcelFileFromDataDyn.mjs'
7
+
8
+
9
+ //Dyn版為相容舊版之保留函數, 內部委派downloadExcelFileFromData, 差異僅在錯誤時reject(非resolve回傳{error})
10
+ //瀏覽器端下載路徑需於瀏覽器測試, 此處測試Node.js端寫檔路徑
11
+ describe(`downloadExcelFileFromDataDyn`, function() {
12
+
13
+ let fdt = './_test_downloadExcelFileFromDataDyn'
14
+
15
+ before(function() {
16
+ fsCreateFolder(fdt)
17
+ })
18
+
19
+ after(function() {
20
+ fsDeleteFolder(fdt)
21
+ })
22
+
23
+ it(`should write an xlsx file in nodejs and roundtrip data`, async function() {
24
+ let fp = `${fdt}/temp.xlsx`
25
+ await downloadExcelFileFromDataDyn(fp, 'data', [['x'], ['1']])
26
+ assert.strict.deepStrictEqual(fs.existsSync(fp), true)
27
+ let u8a = fs.readFileSync(fp)
28
+ let r = await getDataFromExcelFileU8Arr(u8a, { fmt: 'array' })
29
+ assert.strict.deepStrictEqual(r[0].data, [['x'], ['1']])
30
+ })
31
+
32
+ it(`should reject with error message (not resolve {error}) when data is invalid`, async function() {
33
+ let err = null
34
+ try {
35
+ await downloadExcelFileFromDataDyn(`${fdt}/x.xlsx`, 'data', 'not-valid')
36
+ }
37
+ catch (e) {
38
+ err = e
39
+ }
40
+ assert.strict.deepStrictEqual(err, 'data is not an array')
41
+ })
42
+
43
+ })
@@ -2,9 +2,11 @@
2
2
  import assert from 'assert'
3
3
  import replace from '../src/replace.mjs'
4
4
  import b642u8arr from '../src/b642u8arr.mjs'
5
+ import getExcelU8ArrFromData from '../src/getExcelU8ArrFromData.mjs'
5
6
  import getDataFromExcelFileU8Arr from '../src/getDataFromExcelFileU8Arr.mjs'
6
7
 
7
8
 
9
+ //本檔測試一律以await呼叫: 對同步實作與async實作皆可通過, 供Excel引擎抽換時作為行為合約
8
10
  describe(`getDataFromExcelFileU8Arr`, function() {
9
11
 
10
12
  let c = `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`
@@ -33,9 +35,9 @@ describe(`getDataFromExcelFileU8Arr`, function() {
33
35
  core_shape8: 'false'
34
36
  }
35
37
  }
36
- it(`should return ${JSON.stringify(o[k].out)} when input ${JSON.stringify(o[k].in)}`, function() {
38
+ it(`should return ${JSON.stringify(o[k].out)} when input ${JSON.stringify(o[k].in)}`, async function() {
37
39
  let k = 0
38
- let r = getDataFromExcelFileU8Arr(u8a, o[k].in)
40
+ let r = await getDataFromExcelFileU8Arr(u8a, o[k].in)
39
41
  r = r[0].data[1]
40
42
  assert.strict.deepStrictEqual(r, o[k].out)
41
43
  })
@@ -59,9 +61,9 @@ describe(`getDataFromExcelFileU8Arr`, function() {
59
61
  core_shape8: false
60
62
  }
61
63
  }
62
- it(`should return ${JSON.stringify(o[k].out)} when input ${JSON.stringify(o[k].in)}`, function() {
64
+ it(`should return ${JSON.stringify(o[k].out)} when input ${JSON.stringify(o[k].in)}`, async function() {
63
65
  let k = 1
64
- let r = getDataFromExcelFileU8Arr(u8a, o[k].in)
66
+ let r = await getDataFromExcelFileU8Arr(u8a, o[k].in)
65
67
  r = r[0].data[1]
66
68
  assert.strict.deepStrictEqual(r, o[k].out)
67
69
  })
@@ -74,9 +76,9 @@ describe(`getDataFromExcelFileU8Arr`, function() {
74
76
  "2","93002815","BH-1","23","25","false","false","false","true","true","true","true","false"
75
77
  `
76
78
  }
77
- it(`should return ${JSON.stringify(o[k].out)} when input ${JSON.stringify(o[k].in)}`, function() {
79
+ it(`should return ${JSON.stringify(o[k].out)} when input ${JSON.stringify(o[k].in)}`, async function() {
78
80
  let k = 2
79
- let r = getDataFromExcelFileU8Arr(u8a, o[k].in)
81
+ let r = await getDataFromExcelFileU8Arr(u8a, o[k].in)
80
82
  r = replace(r[0].data, '\r\n', '\n')
81
83
  assert.strict.deepStrictEqual(r, o[k].out)
82
84
  })
@@ -86,9 +88,9 @@ describe(`getDataFromExcelFileU8Arr`, function() {
86
88
  in: { fmt: 'csv', valueToString: false },
87
89
  out: `"id","proj_no","hole_no","top_depth","bottom_depth","core_shape1","core_shape2","core_shape3","core_shape4","core_shape5","core_shape6","core_shape7","core_shape8"\r\n1,61602905740006,"BH-6",0,1,false,false,false,false,false,false,false,false\r\n2,93002815,"BH-1",23,25,false,false,false,true,true,true,true,false\r\n`
88
90
  }
89
- it(`should return ${JSON.stringify(o[k].out)} when input ${JSON.stringify(o[k].in)}`, function() {
91
+ it(`should return ${JSON.stringify(o[k].out)} when input ${JSON.stringify(o[k].in)}`, async function() {
90
92
  let k = 3
91
- let r = getDataFromExcelFileU8Arr(u8a, o[k].in)
93
+ let r = await getDataFromExcelFileU8Arr(u8a, o[k].in)
92
94
  r = r[0].data
93
95
  // r = replace(r[0].data, '\r\n', '\n') //vs code內文字換行符號為\n
94
96
  assert.strict.deepStrictEqual(r, o[k].out)
@@ -107,9 +109,9 @@ describe(`getDataFromExcelFileU8Arr`, function() {
107
109
  'false'
108
110
  ]
109
111
  }
110
- it(`should return ${JSON.stringify(o[k].out)} when input ${JSON.stringify(o[k].in)}`, function() {
112
+ it(`should return ${JSON.stringify(o[k].out)} when input ${JSON.stringify(o[k].in)}`, async function() {
111
113
  let k = 4
112
- let r = getDataFromExcelFileU8Arr(u8a, o[k].in)
114
+ let r = await getDataFromExcelFileU8Arr(u8a, o[k].in)
113
115
  r = r[0].data[1]
114
116
  assert.strict.deepStrictEqual(r, o[k].out)
115
117
  })
@@ -127,11 +129,43 @@ describe(`getDataFromExcelFileU8Arr`, function() {
127
129
  false
128
130
  ]
129
131
  }
130
- it(`should return ${JSON.stringify(o[k].out)} when input ${JSON.stringify(o[k].in)}`, function() {
132
+ it(`should return ${JSON.stringify(o[k].out)} when input ${JSON.stringify(o[k].in)}`, async function() {
131
133
  let k = 5
132
- let r = getDataFromExcelFileU8Arr(u8a, o[k].in)
134
+ let r = await getDataFromExcelFileU8Arr(u8a, o[k].in)
133
135
  r = r[0].data[1]
134
136
  assert.strict.deepStrictEqual(r, o[k].out)
135
137
  })
136
138
 
139
+ it(`should omit keys for blank cells in fmt='ltdt' (not fill with '')`, async function() {
140
+ //ltdt模式空cell為略鍵而非給空字串, 為既有sheet_to_json預設語意, 引擎抽換後亦須保持
141
+ let ub = await getExcelU8ArrFromData([['h1', 'h2', 'h3'], ['a', null, 'c']])
142
+ let r1 = await getDataFromExcelFileU8Arr(ub, { fmt: 'ltdt' })
143
+ assert.strict.deepStrictEqual(r1[0].data, [{ h1: 'a', h3: 'c' }])
144
+ let r2 = await getDataFromExcelFileU8Arr(ub, { fmt: 'ltdt', valueToString: false })
145
+ assert.strict.deepStrictEqual(r2[0].data, [{ h1: 'a', h3: 'c' }])
146
+ })
147
+
148
+ it(`should keep '' value (not omit key) for empty-string cells in fmt='ltdt'`, async function() {
149
+ //空字串cell是實體cell, 與空cell(略鍵)不同, 鍵須存在且值為''
150
+ let ub = await getExcelU8ArrFromData([['h1', 'h2'], ['a', '']])
151
+ let r = await getDataFromExcelFileU8Arr(ub, { fmt: 'ltdt' })
152
+ assert.strict.deepStrictEqual(r[0].data, [{ h1: 'a', h2: '' }])
153
+ })
154
+
155
+ it(`should return error object when u8a is not a valid xlsx binary`, async function() {
156
+ //SheetJS舊實作會將垃圾bytes靜默fallback成csv解析而回假成功, 改用hucre後正確回報錯誤
157
+ let r = await getDataFromExcelFileU8Arr(new Uint8Array([1, 2, 3]), { fmt: 'array' })
158
+ assert.strict.deepStrictEqual(r.error, 'can not read data from u8a')
159
+ })
160
+
161
+ it(`should return error object when opt.fmt is invalid`, async function() {
162
+ let r = await getDataFromExcelFileU8Arr(u8a, { fmt: 'xxx' })
163
+ assert.strict.deepStrictEqual(r.error, `opt.fmt is not one of 'ltdt', 'csv', 'array'`)
164
+ })
165
+
166
+ it(`should return error object when opt.valueToString is invalid`, async function() {
167
+ let r = await getDataFromExcelFileU8Arr(u8a, { fmt: 'array', valueToString: 'x' })
168
+ assert.strict.deepStrictEqual(r.error, 'opt.valueToString is not a boolean')
169
+ })
170
+
137
171
  })