@scenetechnology/cj_element_table 0.0.1

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 (61) hide show
  1. package/.browserslistrc +4 -0
  2. package/.env.base +11 -0
  3. package/.env.dev +23 -0
  4. package/.env.gitee +23 -0
  5. package/.env.pro +24 -0
  6. package/.env.test +23 -0
  7. package/.eslintrc.js +18 -0
  8. package/README.md +24 -0
  9. package/babel.config.js +6 -0
  10. package/dist/cj_element_table.common.js +66535 -0
  11. package/dist/cj_element_table.common.js.map +1 -0
  12. package/dist/cj_element_table.css +1 -0
  13. package/dist/cj_element_table.umd.js +66554 -0
  14. package/dist/cj_element_table.umd.js.map +1 -0
  15. package/dist/cj_element_table.umd.min.js +61 -0
  16. package/dist/cj_element_table.umd.min.js.map +1 -0
  17. package/dist/demo.html +1 -0
  18. package/package.json +42 -0
  19. package/packages/components/SaveViewDialog.vue +109 -0
  20. package/packages/components/exportExcel.js +305 -0
  21. package/packages/components/exportTable.vue +361 -0
  22. package/packages/components/historyDialog.vue +100 -0
  23. package/packages/components/index.vue +1235 -0
  24. package/packages/components/tablesetting.vue +344 -0
  25. package/packages/components/tuo-drag.vue +197 -0
  26. package/packages/components/viewEdit.vue +239 -0
  27. package/packages/index.js +13 -0
  28. package/public/favicon.ico +0 -0
  29. package/public/index.html +17 -0
  30. package/src/App.vue +59 -0
  31. package/src/api/All.ts +104 -0
  32. package/src/assets/images/TablehederTool.png +0 -0
  33. package/src/assets/images/addIcon.png +0 -0
  34. package/src/assets/images/blue_lock.png +0 -0
  35. package/src/assets/images/changeIcon.png +0 -0
  36. package/src/assets/images/downImg.png +0 -0
  37. package/src/assets/images/kong_icon.png +0 -0
  38. package/src/assets/images/lbIcon.png +0 -0
  39. package/src/assets/images/lookImg.png +0 -0
  40. package/src/assets/images/model_title_icon.png +0 -0
  41. package/src/assets/images/pgIcon.png +0 -0
  42. package/src/assets/images/pzIcon.png +0 -0
  43. package/src/assets/images/tuozhui_icon.png +0 -0
  44. package/src/assets/images/view_save_icon.png +0 -0
  45. package/src/assets/images/view_setting_icon.png +0 -0
  46. package/src/assets/images/yaIcon.png +0 -0
  47. package/src/assets/logo.png +0 -0
  48. package/src/components/Dialog/index.ts +3 -0
  49. package/src/components/Dialog/src/Dialog.vue +72 -0
  50. package/src/components/HelloWorld.vue +60 -0
  51. package/src/components/Upload/index.vue +287 -0
  52. package/src/config/axios/config.ts +122 -0
  53. package/src/config/axios/index.ts +48 -0
  54. package/src/config/axios/service.ts +118 -0
  55. package/src/main.ts +13 -0
  56. package/src/router/index.ts +16 -0
  57. package/src/shims-vue.d.ts +6 -0
  58. package/tsconfig.json +41 -0
  59. package/types/global.d.ts +39 -0
  60. package/types/vite-env.d.ts +0 -0
  61. package/vue.config.js +24 -0
package/dist/demo.html ADDED
@@ -0,0 +1 @@
1
+ <!doctype html><meta charset="utf-8"><title>cj_element_table demo</title><script src="./cj_element_table.umd.js"></script><link rel="stylesheet" href="./cj_element_table.css"><script>console.log(cj_element_table)</script>
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@scenetechnology/cj_element_table",
3
+ "version": "0.0.1",
4
+ "private": false,
5
+ "description": "element plus 3.0 表格组件",
6
+ "main": "dist/cj_element_table.umd.min.js",
7
+ "scripts": {
8
+ "serve": "vue-cli-service serve",
9
+ "build": "vue-cli-service build",
10
+ "lint": "vue-cli-service lint",
11
+ "build:lib": "vue-cli-service build --target lib --name cj_element_table packages/index.js"
12
+ },
13
+ "dependencies": {
14
+ "axios": "^1.8.4",
15
+ "element-plus": "^2.9.7",
16
+ "exceljs": "^4.4.0",
17
+ "file-saver": "^2.0.5",
18
+ "less": "^4.3.0",
19
+ "less-loader": "^12.2.0",
20
+ "pinia": "^3.0.1",
21
+ "vue": "^3.2.13",
22
+ "vue-router": "^4.5.0",
23
+ "vue-types": "^6.0.0",
24
+ "web-storage-cache": "^1.1.1"
25
+ },
26
+ "devDependencies": {
27
+ "@babel/core": "^7.26.10",
28
+ "@typescript-eslint/eslint-plugin": "^5.4.0",
29
+ "@typescript-eslint/parser": "^5.4.0",
30
+ "@vitejs/plugin-vue-jsx": "^4.1.2",
31
+ "@vue/babel-plugin-jsx": "^1.4.0",
32
+ "@vue/babel-preset-app": "^5.0.8",
33
+ "@vue/cli-plugin-babel": "^5.0.8",
34
+ "@vue/cli-plugin-eslint": "~5.0.0",
35
+ "@vue/cli-plugin-typescript": "~5.0.0",
36
+ "@vue/cli-service": "~5.0.0",
37
+ "@vue/eslint-config-typescript": "^9.1.0",
38
+ "eslint": "^7.32.0",
39
+ "eslint-plugin-vue": "^8.0.3",
40
+ "typescript": "~4.9.5"
41
+ }
42
+ }
@@ -0,0 +1,109 @@
1
+ <template>
2
+ <el-dialog v-model="dialogVisible" @clickClose="closeDialog" :title="title" width="600" max-height="600">
3
+ <el-input v-model="viewForm.name" :maxlength="maxLength" placeholder="请输入视图名称" style="width:100%;margin:20px 0 10px 0;" />
4
+ <el-radio-group v-model="viewForm.type" style="margin: 10px 0;">
5
+ <el-radio label="2">个人视图</el-radio>
6
+ <el-radio label="1">公共视图</el-radio>
7
+ </el-radio-group>
8
+ <div class="tips">
9
+ <el-icon><WarningFilled /></el-icon>保存的列表视图包含筛选条件、列表排序、表头排序等信息
10
+ </div>
11
+ <template #footer>
12
+ <ElButton type="primary" :loading="loading" @click="handleSave">提交</ElButton>
13
+ <ElButton @click="closeDialog">取消</ElButton>
14
+ </template>
15
+ </el-dialog>
16
+ </template>
17
+
18
+ <script setup lang="ts">
19
+ import { ref, defineProps, defineEmits,watch } from 'vue'
20
+ import { ElInput, ElRadioGroup, ElRadio, ElButton, ElIcon,ElMessage } from 'element-plus'
21
+ import { WarningFilled } from '@element-plus/icons-vue'
22
+ import { Dialog } from '@/components/Dialog'
23
+ import { Form } from '../Form'
24
+
25
+ const props = defineProps({
26
+ modelValue: {
27
+ type: Boolean,
28
+ default: false
29
+ },
30
+ title: {
31
+ type: String,
32
+ default: ''
33
+ },
34
+ maxLength: {
35
+ type: Number,
36
+ default: 50
37
+ },
38
+ Form: {
39
+ type: Object,
40
+ default: () => ({})
41
+ }
42
+ })
43
+
44
+ const emit = defineEmits(['update:modelValue', 'save'])
45
+
46
+ const dialogVisible = ref(props.modelValue)
47
+ const loading = ref(false)
48
+ const viewForm = ref({
49
+ name: '',
50
+ type: '2',...props.Form})
51
+
52
+ // 监听modelValue变化
53
+ watch(() => props.modelValue, (val) => {
54
+ dialogVisible.value = val
55
+ })
56
+ watch(() => props.Form, (val) => {
57
+ viewForm.value = val
58
+ })
59
+ // 监听dialogVisible变化
60
+ watch(() => dialogVisible.value, (val) => {
61
+ emit('update:modelValue', val)
62
+ })
63
+
64
+ const closeDialog = () => {
65
+ dialogVisible.value = false
66
+ viewForm.value = {
67
+ name: '',
68
+ type: '2'
69
+ }
70
+ }
71
+
72
+ const handleSave = async () => {
73
+ if (!viewForm.value.name) {
74
+ ElMessage.warning('请输入视图名称')
75
+ return
76
+ }else{
77
+ loading.value = true
78
+ try {
79
+ emit('save', viewForm.value)
80
+ } finally {
81
+ loading.value = false
82
+ }
83
+ }
84
+
85
+ }
86
+ </script>
87
+
88
+ <style scoped>
89
+ .tips {
90
+ color: #909399;
91
+ font-size: 12px;
92
+ margin-top: 10px;
93
+ }
94
+
95
+ .tips .el-icon {
96
+ margin-right: 5px;
97
+ vertical-align: middle;
98
+ }
99
+ .tips{
100
+ color:rgb(255, 128, 44);
101
+ display: flex;
102
+ justify-content: flex-start;
103
+ align-items: center;
104
+ margin-bottom: 10px;
105
+ i{
106
+ margin-right: 10px;
107
+ }
108
+ }
109
+ </style>
@@ -0,0 +1,305 @@
1
+ /**
2
+ * exceljs 封装
3
+ * author:yf
4
+ * time:20220323
5
+ * 博客:https://www.jianshu.com/p/27e8a5cfc420
6
+ * */
7
+ import ExcelJS from 'exceljs'
8
+ import FileSaver from 'file-saver'
9
+
10
+ function isNullFn(val) {
11
+ return val === null || val === void 0 || val === '' || (val).toString() === 'NaN'
12
+ }
13
+
14
+ /**
15
+ * 将chart与index计算,原理是使用ascii计算
16
+ * @chart:参与计算的字母,这里代表excel的列A ->Z
17
+ *
18
+ * */
19
+ // function chartCalFn(chart, index) {
20
+ // return String.fromCharCode(chart.charCodeAt() + index)
21
+ // }
22
+ function chartCalFn(chart, index) {
23
+ let columnLetter = '';
24
+ let charCode = chart.charCodeAt(chart.length - 1);
25
+ let newCharCode = charCode + index;
26
+
27
+ if (newCharCode > 'Z'.charCodeAt()) {
28
+ // Handle overflow, i.e., 'Z' + 1 -> 'AA'
29
+ let carry = Math.floor((newCharCode - 'A'.charCodeAt()) / 26);
30
+ let remainder = (newCharCode - 'A'.charCodeAt()) % 26;
31
+ columnLetter = String.fromCharCode('A'.charCodeAt() + remainder);
32
+ if (carry > 0) {
33
+ columnLetter = String.fromCharCode('A'.charCodeAt() + carry - 1) + columnLetter;
34
+ }
35
+ } else {
36
+ columnLetter = String.fromCharCode(newCharCode);
37
+ }
38
+
39
+ return columnLetter;
40
+ }
41
+
42
+ // 获取换算后行的位置。 如 2、25等
43
+ function getRowFn(tableRef, index) {
44
+ let startRow = parseInt(tableRef.replace(/[A-Z]/g, '')) // 表格开始的行位置
45
+ return startRow + parseInt(index)
46
+ }
47
+
48
+ // 获取换算后列的位置, 如:B、BC等
49
+ function getColumnFn(tableRef, index) {
50
+ // tableRef可能为 AA等
51
+ let startCol = tableRef.replace(/[0-9]/g, '') // 表格开始的列位置
52
+
53
+ let before = startCol.substr(0, startCol.length - 1) // 前面的字母
54
+ let after = startCol.substr(startCol.length - 1, 1) // 最后一位字母
55
+
56
+ return before + '' + chartCalFn(after, index)
57
+ }
58
+
59
+ /**
60
+ * 获取换算后的单元格位置
61
+ * @tableRef: 表格左上角位置
62
+ * @coords: 需要平移的坐标,格式:[需要横向平移的个数,需要纵向平移的个数]
63
+ * return String 返回平移行列后的单元格位置
64
+ * */
65
+ function getCellFn(tableRef, coords) {
66
+ if (!coords || coords.length !== 2) {
67
+ console.error('坐标错误')
68
+ return tableRef
69
+ }
70
+ return getColumnFn(tableRef, coords[0]) + '' + getRowFn(tableRef, coords[1])
71
+ }
72
+
73
+ /**
74
+ * excel 导出表格
75
+ * @tableConfigArr: 同exceljs sheet.addTable参数 参考 https://github.com/exceljs/exceljs/blob/master/README_zh.md#%E8%A1%A8%E6%A0%BC
76
+ * 注意:1.columns中的_width属性是为了这里便于封装使用的,用于设置表格列宽,exceljs 官网没有此属性,别混淆
77
+ * 2._tableBorder?: boolean 可选封装参数,true 则导出的表格有边框 false 则看表格的theme
78
+ * 3._mergeCells?: [Array<string>] 可选封装参数,需要合并的单元格. eg: [['C3:C5']]
79
+ * 4._cellStyle?: [{ // 单元格样式设置
80
+ * coords:[0,2], // 如表格ref为C3,则这里表示的是C5 [横坐标,纵坐标],可以理解为以表格左上角为原点
81
+ * style:{} // 同exceljs 单元格样式 参考https://github.com/exceljs/exceljs/blob/master/README_zh.md#%E6%A0%B7%E5%BC%8F
82
+ * }]
83
+ * 5._sheetRefName?: string 注意:当customConfig.sheetName 设置为数组的时候,也就是有多个选项卡的时候,不写此参数则,默认加入第一张sheet
84
+ *
85
+ * @customConfig: {
86
+ * sheetName: string || Array 表格选项卡名称
87
+ * 当为数组sheetName时,sheetName 单项可为string代表名称,可为对象,结构如下:
88
+ * {"name": "sheet1",
89
+ * "option": { // option同exceljs 工作表 参考:https://github.com/exceljs/exceljs/blob/master/README_zh.md#%E5%B7%A5%E4%BD%9C%E8%A1%A8%E5%B1%9E%E6%80%A7
90
+ * "properties": {"tabColor": {"argb": "FFC0000"}}}
91
+ * }
92
+ * fileName: string 导出的excel文件名,如:test
93
+ * }
94
+ * */
95
+ // 参数如下:
96
+ // 参数说明:为了更友好的参考官网,这里封装的结构基本和exceljs官网一致,但某些为了方便调用的配置的参数,都以 "_"开头,如:_width,_cellStyle,_mergeCells,_tableBorder
97
+ // tableConfigArr 结构如下:
98
+ // [
99
+ // {
100
+ // "name": "MyTestTable",
101
+ // "ref": "C3",
102
+ // "headerRow": false,
103
+ // "totalsRow": false,
104
+ // "style": {"theme": "TableStyleLight1"},
105
+ // "columns": [
106
+ // {"name": "日期", "_width": 30},
107
+ // {"name": "姓名", "_width": 30},
108
+ // {"name": "省份", "_width": 30},
109
+ // ],
110
+ // "rows": [
111
+ // ["2016-05-02", "王小虎", "上海"],
112
+ // ["2016-05-03", "王小虎", "上海"],
113
+ // ],
114
+ // "_tableBorder": true,
115
+ // "_mergeCells": [
116
+ // ["C3:C5"],
117
+ // ["D3:H3"],
118
+ // ],
119
+ // "_cellStyle": [ // 单元格样式设置,代表表格左上角平移1列2行后的单元格,如表格ref为C3,则这里表示的是D5 [横坐标,纵坐标],可以理解为以表格左上角为原点,
120
+ // {
121
+ // "coords": [0, 2],
122
+ // "style": {"alignment": {"vertical": "middle", "horizontal": "left"}}
123
+ // },
124
+ // ],
125
+ // "_sheetRefName": "sheet2"
126
+ // }
127
+ // ],
128
+ // customConfig 结构如下:
129
+ // {
130
+ // "sheetName": [
131
+ // {"name": "sheet1", "option": {"properties": {"tabColor": {"argb": "FFC0000"}}}},
132
+ // "sheet2"
133
+ // ],
134
+ // "fileName": "合并表头的表格导出"
135
+ // }
136
+ export function $export(tableConfigArr, customConfig) {
137
+ let { sheetName, fileName } = customConfig
138
+ const workbook = new ExcelJS.Workbook();
139
+ workbook.creator = 'admin';
140
+ workbook.lastModifiedBy = 'admin';
141
+ workbook.created = new Date();
142
+ workbook.modified = new Date();
143
+ workbook.lastPrinted = new Date();
144
+
145
+ // 创建带有红色标签颜色的工作表
146
+ // const sheet = workbook.addWorksheet(sheetName, {properties: {tabColor: {argb: 'FFC0000'}}});
147
+
148
+ // 生成 sheet start ----------
149
+ let sheetname = null
150
+ if (Array.isArray(sheetName)) { // 多个工作表
151
+ sheetname = sheetName[0].name ? sheetName[0].name : sheetName[0]
152
+ sheetName.map(item => {
153
+ workbook.addWorksheet(item.name ? item.name : item, item.option || {});
154
+ })
155
+
156
+ } else { // 只有一个工作表
157
+ if (typeof sheetName === 'string') {
158
+ sheetname = sheetName
159
+ workbook.addWorksheet(sheetName);
160
+ } else {
161
+ sheetname = sheetName.name
162
+ workbook.addWorksheet(sheetname, sheetName.option || {});
163
+ }
164
+ }
165
+ // 生成 sheet end ----------
166
+
167
+ let sheet = null;
168
+ tableConfigArr.map(tableConfig => {
169
+
170
+ let { ref: tableRef, _sheetRefName } = tableConfig // 因为tableRef可能为 AE:2 这种组合
171
+
172
+ if (_sheetRefName) { // 指定了插入哪个sheet
173
+ // 按 name 提取工作表
174
+ sheet = workbook.getWorksheet(_sheetRefName);
175
+ } else {
176
+ sheet = workbook.getWorksheet(sheetname);
177
+ }
178
+ console.log('sheet----', sheet)
179
+
180
+ // table-列宽设置 start -------
181
+ let { columns } = tableConfig
182
+ columns.map((item, index) => {
183
+ if (isNullFn(item._width)) return // 没有设置宽度使用exceljs默认宽
184
+ let currentChart = sheet.getColumn(getColumnFn(tableRef, index))
185
+ currentChart.width = item._width // 设置列宽度
186
+ })
187
+ // table-列宽设置 end -------
188
+
189
+ // 单元格合并 start --------
190
+ let { _mergeCells } = tableConfig
191
+ _mergeCells && _mergeCells.length && _mergeCells.map(item => {
192
+ sheet.mergeCells(item);
193
+ })
194
+ // 单元格合并 end --------
195
+
196
+ // 单元格样式设置 start ------
197
+ let { _cellStyle } = tableConfig
198
+ _cellStyle && _cellStyle.length && _cellStyle.map(item => {
199
+ let cell = sheet.getCell(getCellFn(tableRef, item.coords))
200
+ item.style && Object.keys(item.style).map(sub => { // 设置单元格样式
201
+ cell[sub] = item.style[sub]
202
+ })
203
+ })
204
+ // 单元格样式设置 end ------
205
+
206
+ // 表格设置边框 start -------
207
+ let { _tableBorder, rows } = tableConfig
208
+ // const imageId2 = workbook.addImage({
209
+ // base64: myBase64Image,
210
+ // extension: 'png',
211
+ // });
212
+
213
+ let imageId2 = ''
214
+ rows.forEach((item1, index1) => {
215
+ item1.forEach((item2, index2) => {
216
+ if (typeof item2 === 'string' && item2.indexOf('data:image') !== -1) {
217
+ // console.log('index1---',index1,'index2---',index2)
218
+ imageId2 = workbook.addImage({
219
+ base64: item2,
220
+ extension: 'png',
221
+ });
222
+ sheet.getRow(index1 + 2).height = 85;
223
+ sheet.getColumn(index2 + 1).width = 30;
224
+ sheet.addImage(imageId2, {
225
+ tl: { col: index2, row: index1 + 1 }, // 图片的左上角所在的单元格
226
+ // br: { col: index2+1, row: index1+2 }, // 图片的右下角所在的单元格
227
+ ext: { width: 85, height: 85 },
228
+ editAs: 'oneCell',
229
+ });
230
+ // sheet.addImage(imageId2, {
231
+ // tl: { col: index2+0.3, row: index1+1 }, // 图片的左上角所在的单元格
232
+ // // br: { col: index2+1, row: index1+2 }, // 图片的右下角所在的单元格
233
+ // ext: { width: 85, height: 85 },
234
+ // editAs: 'oneCell',
235
+ // });
236
+ // row.height = 42.5;
237
+ // 调整单元格的尺寸以适应图片
238
+ // sheet.getRow(index1+2).height = 85;
239
+ // sheet.getColumn(index2+1).width = 200;
240
+ // sheet.addImage(imageId2, 'A3:A3');
241
+
242
+ // sheet.addImage(imageId2, {
243
+ // tl: { col: 6.5, row: 6.5 },
244
+ // br: { col: 6.5, row: 6.5 },
245
+ // ext: { width: 500, height: 200 },
246
+ // editAs: 'oneCell'
247
+ // });
248
+ rows[index1][index2] = ""
249
+ } else if (Array.isArray(item2) && item2.length > 0) {
250
+ for (let itemValue of item2) {
251
+ console.log(itemValue)
252
+ if (typeof itemValue === 'string' && itemValue.indexOf('data:image') !== -1) {
253
+ imageId2 = workbook.addImage({
254
+ base64: itemValue,
255
+ extension: 'png',
256
+ });
257
+ sheet.getRow(index1 + 2).height = 85;
258
+ sheet.getColumn(index2 + 1).width = 30;
259
+ sheet.addImage(imageId2, {
260
+ tl: { col: index2, row: index1 + 1 }, // 图片的左上角所在的单元格
261
+ // br: { col: index2+1, row: index1+2 }, // 图片的右下角所在的单元格
262
+ ext: { width: 85, height: 85 },
263
+ editAs: 'oneCell',
264
+ });
265
+ }
266
+ }
267
+ rows[index1][index2] = ""
268
+ }
269
+ })
270
+ })
271
+ console.log('rows--', rows)
272
+ if (_tableBorder) {
273
+ let { columns, rows, headerRow, totalsRow } = tableConfig
274
+ let rowMaxIndex = rows.length
275
+ headerRow && (rowMaxIndex++); // 有标题行则+1
276
+ totalsRow && (rowMaxIndex++); // 有合计行则+1
277
+ let colMaxIndex = columns.length
278
+
279
+ for (let rowIndex = 0; rowIndex < rowMaxIndex; rowIndex++) {
280
+ for (let colIndex = 0; colIndex < colMaxIndex; colIndex++) {
281
+ let cell = sheet.getCell(getCellFn(tableRef, [colIndex, rowIndex]))
282
+ cell.border = {
283
+ top: { style: 'thin' },
284
+ left: { style: 'thin' },
285
+ bottom: { style: 'thin' },
286
+ right: { style: 'thin' }
287
+ }
288
+ }
289
+ }
290
+ }
291
+
292
+
293
+ // 表格设置边框 end -------
294
+
295
+ sheet.addTable(tableConfig)
296
+ })
297
+
298
+ // workbook.xlsx.writeFile('test.xlsx') // node端才能使用
299
+ workbook.xlsx.writeBuffer().then(buffer => {
300
+ console.log('文件更新成功');
301
+ FileSaver.saveAs(new Blob([buffer], { type: 'application/octet-stream' }), `${fileName || 'excel'}.xlsx`);
302
+ }).catch((err) => {
303
+ console.error('操作文件时出错:', err);
304
+ });
305
+ }