index.html 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. <!DOCTYPE html>
  2. <html>
  3. <head lang="zh">
  4. <meta charset="utf-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="renderer" content="webkit" />
  7. <meta name="viewport" content="width=device-width, initial-scale=1,user-scalable=0" />
  8. <title>Luckysheet</title>
  9. <link rel="stylesheet" href="./plugins/css/pluginsCss.css" />
  10. <link rel="stylesheet" href="./plugins/plugins.css" />
  11. <link rel="stylesheet" href="./css/luckysheet.css" />
  12. <link rel="stylesheet" href="./assets/iconfont/iconfont.css" />
  13. <script src="./plugins/js/plugin.js"></script>
  14. <!-- rollup luckysheet.js -->
  15. <script src="./luckysheet.umd.js"></script>
  16. <script src="./demoData/sheetVchart.js"></script>
  17. <script src="./demoData/sheetChart.js"></script>
  18. <script src="./demoData/sheetCell.js"></script>
  19. <script src="./demoData/sheetPicture.js"></script>
  20. <script src="./demoData/sheetRemoteSelect.js"></script>
  21. </head>
  22. <body>
  23. <div id="luckysheet" style="margin: 0px; padding: 0px; position: absolute; width: 100%; height: 100%; left: 0px; top: 0px"></div>
  24. <script>
  25. // 公共配置项
  26. const commonOptions = {
  27. container: "luckysheet",
  28. lang: "zh",
  29. showinfobar: false, // 隐藏信息栏
  30. showlogo: false, // 隐藏logo
  31. plugins: [{ name: "vchart" }, { name: "chart" }],
  32. data: [sheetCell],
  33. // 打印像素比,设置越高,越清晰
  34. printDevicePixelRatio: 100,
  35. // 是否需要打印预览
  36. // printPreview: false,
  37. // 图片显示方式
  38. imageMode: "cell", // 'cell' | 'float'
  39. // 自定义快捷键
  40. customShortcutKeys: [
  41. {
  42. key: 83,
  43. ctrl: true,
  44. callback: (e) => {
  45. console.log("Ctrl S");
  46. },
  47. },
  48. {
  49. key: 80,
  50. ctrl: true,
  51. callback: (e) => {
  52. luckysheet.print({ mode: "sheet" });
  53. },
  54. },
  55. ],
  56. // 自定义右键菜单
  57. cellRightClickConfig: {
  58. // copy: false,
  59. copyAs: false,
  60. // paste: false,
  61. hideColumn: false,
  62. columnWidth: false,
  63. clear: false,
  64. matrix: false,
  65. sort: false,
  66. filter: false,
  67. chart: true,
  68. image: true,
  69. link: false,
  70. data: false,
  71. cellFormat: false,
  72. customs: [
  73. {
  74. title: "test",
  75. onClick: function (clickEvent, event, params) {
  76. console.log("function test click", clickEvent, event, params);
  77. },
  78. },
  79. ],
  80. },
  81. // 项目菜单
  82. menuHandler: {
  83. // 隐藏内置菜单
  84. // hideDefaultMenu: ['exportFile', 'importFile'],
  85. // 自定义
  86. customs: [
  87. // 分割线
  88. {
  89. order: 0,
  90. label: "自定义菜单",
  91. value: "newFile",
  92. callback: () => {
  93. console.log("==> 自定义菜单");
  94. },
  95. },
  96. {
  97. order: 0,
  98. value: "divider",
  99. },
  100. ],
  101. },
  102. // loading 样式
  103. loading: {
  104. image: () => {
  105. return `<svg viewBox="25 25 50 50" class="circular">
  106. <circle cx="50" cy="50" r="20" fill="none"></circle>
  107. </svg>`;
  108. },
  109. imageClass: "loadingAnimation",
  110. },
  111. };
  112. // 处理协同图片上传
  113. async function uploadImage(file, serviceServer) {
  114. // 此处拿到的是上传的 file 对象,进行文件上传 ,配合 node 接口实现
  115. const formData = new FormData();
  116. formData.append("image", file);
  117. // 结合 Ajax 实现图片上传
  118. return new Promise((resolve, reject) => {
  119. $.ajax({
  120. url: `${serviceServer}/uploadImage`,
  121. type: "POST",
  122. data: formData,
  123. processData: false,
  124. contentType: false,
  125. success: function (res) {
  126. if (res.code === 200) resolve(res.url);
  127. else reject("image upload error");
  128. },
  129. error: function (err) {
  130. reject("image upload error");
  131. },
  132. });
  133. });
  134. }
  135. // 处理上传图片的地址
  136. function imageUrlHandle(url, serviceServer) {
  137. // 已经是 // http data 开头则不处理
  138. if (/^(?:\/\/|(?:http|https|data):)/i.test(url)) return url;
  139. // 不然拼接服务器路径
  140. return serviceServer + url;
  141. }
  142. // 动态获取 luadUrl
  143. function getLoadUrl(serviceServer, currentBranch, gridkey) {
  144. return `${serviceServer}${currentBranch === "master-alpha" ? "/" : "/luckysheet/"}loadSheetData?gridkey=${gridkey}`;
  145. }
  146. // 动态获取 updateUrl
  147. function getUpdateUrl(collabrationServer, currentBranch, userid, username, gridkey) {
  148. return `${collabrationServer}
  149. ${currentBranch === "master-alpha" ? "?" : "/luckysheet?"}
  150. type=luckysheet&userid=${userid}&username=${username}&gridkey=${gridkey}`;
  151. }
  152. // 根据协同与否,动态获取配置
  153. function getOptions(isCollabration, requestHeaders = {}, serviceServer, collabrationServer, currentBranch, userid, username, gridkey) {
  154. // 如果没有开启协同,则直接返回基础配置
  155. if (!isCollabration) return Object.assign({}, commonOptions, { requestHeaders });
  156. return Object.assign({}, commonOptions, {
  157. // 如果是 master-vue 的话,还需要添加自定义请求头,请检查合并属性哈,不然容易遗漏属性
  158. requestHeaders:
  159. currentBranch === "master-vue"
  160. ? {
  161. "enable-pass-token": true, // 是否允许跳过 token 验证
  162. ...requestHeaders,
  163. }
  164. : requestHeaders,
  165. allowUpdate: true, // 配置协同功能
  166. loadUrl: getLoadUrl(serviceServer, currentBranch, gridkey),
  167. updateUrl: getUpdateUrl(collabrationServer, currentBranch, userid, username, gridkey), // 协同服务转发服务
  168. // 如果配置了协同,请配置图片处理函数,避免base64图片过大导致图片无法显示
  169. uploadImage: (file) => uploadImage(file, serviceServer),
  170. imageUrlHandle: (url) => imageUrlHandle(url, serviceServer),
  171. });
  172. }
  173. /**
  174. * @description 页面初始化相关工作
  175. */
  176. $(function () {
  177. /**
  178. * -------------------------------------------------------
  179. * ⚠️ 注意:请严格按照下列步骤进行配置,否则会导致无法协同 ⚠️
  180. * -------------------------------------------------------
  181. */
  182. // 1. 请明确协同服务地址
  183. const collabrationServer = "ws://localhost:9000";
  184. // 2. 请明确业务服务地址
  185. const serviceServer = "http://localhost:9000";
  186. // 3. 请明确 `luckysheet-crdt` 项目目前所在的分支,因为 master-alpha 与 master-vue 分支所在的服务端不尽相同,`master-vue` 分支需要校验 token
  187. const currentBranch = "master-alpha"; // "master-vue" | "master-alpha"
  188. // 4. 定义 userid 内部 userid 可随机生成
  189. const userid = Math.random().toString(16).slice(2, 8);
  190. // 5. username 字段 仅用于显示 xxx正在编辑 (对中文进行编码传输,避免乱码)
  191. const username = encodeURIComponent(`用户_${userid}`);
  192. // 6. 这个是协同的文件 gridKey 请真实的设置为数据库的 key,不然会提示协同服务异常 是真实数据库表的 workerbooks gridKey 字段
  193. const gridkey = "gridkey_demo";
  194. // 7. 明确是否需要协同功能
  195. const isCollabration = false;
  196. // 8. 是否需要携带其他 request headers
  197. const requestHeaders = {
  198. // "Custom-userid": userid,
  199. };
  200. // 9. 根据是否需要协同功能,动态获取配置项
  201. const options = getOptions(isCollabration, requestHeaders, serviceServer, collabrationServer, currentBranch, userid, username, gridkey);
  202. // 10. 创建表格
  203. luckysheet.create(options);
  204. });
  205. </script>
  206. </body>
  207. </html>