feat: add table td border type

pr675
Hufe921 3 years ago
parent 7260b6439b
commit d8876b1095

@ -419,6 +419,16 @@ Usage:
instance.command.executeTableBorderType(payload: TableBorder) instance.command.executeTableBorderType(payload: TableBorder)
``` ```
## executeTableTdBorderType
Feature: Table td border type
Usage:
```javascript
instance.command.executeTableTdBorderType(payload: TableBorder)
```
## executeTableTdBackgroundColor ## executeTableTdBackgroundColor
Feature: Table cell background color Feature: Table cell background color

@ -63,6 +63,8 @@ interface ILang {
borderAll: string borderAll: string
borderEmpty: string borderEmpty: string
borderExternal: string borderExternal: string
borderTd: string
borderTdBottom: string
} }
} }
datePicker: { datePicker: {

@ -54,6 +54,7 @@ interface IElement {
rowspan: number; rowspan: number;
verticalAlign?: VerticalAlign; verticalAlign?: VerticalAlign;
backgroundColor?: string; backgroundColor?: string;
borderType?: TdBorder;
value: IElement[]; value: IElement[];
}[]; }[];
}[]; }[];

@ -419,6 +419,16 @@ instance.command.executeTableTdVerticalAlign(payload: VerticalAlign)
instance.command.executeTableBorderType(payload: TableBorder) instance.command.executeTableBorderType(payload: TableBorder)
``` ```
## executeTableTdBorderType
功能:表格单元格边框类型
用法:
```javascript
instance.command.executeTableTdBorderType(payload: TdBorder)
```
## executeTableTdBackgroundColor ## executeTableTdBackgroundColor
功能:表格单元格背景色 功能:表格单元格背景色

@ -63,6 +63,8 @@ interface ILang {
borderAll: string borderAll: string
borderEmpty: string borderEmpty: string
borderExternal: string borderExternal: string
borderTd: string
borderTdBottom: string
} }
} }
datePicker: { datePicker: {

@ -54,6 +54,7 @@ interface IElement {
rowspan: number; rowspan: number;
verticalAlign?: VerticalAlign; verticalAlign?: VerticalAlign;
backgroundColor?: string; backgroundColor?: string;
borderType?: TdBorder;
value: IElement[]; value: IElement[];
}[]; }[];
}[]; }[];

@ -158,3 +158,11 @@
.ce-contextmenu-border-external { .ce-contextmenu-border-external {
background-image: url(../../../assets/images/table-border-external.svg); background-image: url(../../../assets/images/table-border-external.svg);
} }
.ce-contextmenu-border-td {
background-image: url(../../../assets/images/table-border-td.svg);
}
.ce-contextmenu-border-td-bottom {
background-image: url(../../../assets/images/table-border-td-bottom.svg);
}

@ -0,0 +1 @@
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2.5 3a.5.5 0 01.5-.5h11a.5.5 0 01.5.5v11a.5.5 0 01-.5.5H3a.5.5 0 01-.5-.5V3z" stroke="#AAACB0"/><path stroke="#3D4757" d="M2.5 8.5 h12"/></svg>

After

Width:  |  Height:  |  Size: 228 B

@ -0,0 +1 @@
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2.5 3a.5.5 0 01.5-.5h11a.5.5 0 01.5.5v11a.5.5 0 01-.5.5H3a.5.5 0 01-.5-.5V3z" stroke="#AAACB0"/><path stroke="#3D4757" d="M8.5 2.5 v6 h-6"/></svg>

After

Width:  |  Height:  |  Size: 231 B

@ -43,6 +43,7 @@ export class Command {
public executeCancelMergeTableCell: CommandAdapt['cancelMergeTableCell'] public executeCancelMergeTableCell: CommandAdapt['cancelMergeTableCell']
public executeTableTdVerticalAlign: CommandAdapt['tableTdVerticalAlign'] public executeTableTdVerticalAlign: CommandAdapt['tableTdVerticalAlign']
public executeTableBorderType: CommandAdapt['tableBorderType'] public executeTableBorderType: CommandAdapt['tableBorderType']
public executeTableTdBorderType: CommandAdapt['tableTdBorderType']
public executeTableTdBackgroundColor: CommandAdapt['tableTdBackgroundColor'] public executeTableTdBackgroundColor: CommandAdapt['tableTdBackgroundColor']
public executeTableSelectAll: CommandAdapt['tableSelectAll'] public executeTableSelectAll: CommandAdapt['tableSelectAll']
public executeImage: CommandAdapt['image'] public executeImage: CommandAdapt['image']
@ -143,6 +144,7 @@ export class Command {
this.executeCancelMergeTableCell = adapt.cancelMergeTableCell.bind(adapt) this.executeCancelMergeTableCell = adapt.cancelMergeTableCell.bind(adapt)
this.executeTableTdVerticalAlign = adapt.tableTdVerticalAlign.bind(adapt) this.executeTableTdVerticalAlign = adapt.tableTdVerticalAlign.bind(adapt)
this.executeTableBorderType = adapt.tableBorderType.bind(adapt) this.executeTableBorderType = adapt.tableBorderType.bind(adapt)
this.executeTableTdBorderType = adapt.tableTdBorderType.bind(adapt)
this.executeTableTdBackgroundColor = this.executeTableTdBackgroundColor =
adapt.tableTdBackgroundColor.bind(adapt) adapt.tableTdBackgroundColor.bind(adapt)
this.executeTableSelectAll = adapt.tableSelectAll.bind(adapt) this.executeTableSelectAll = adapt.tableSelectAll.bind(adapt)

@ -13,7 +13,7 @@ import { ElementType } from '../../dataset/enum/Element'
import { ElementStyleKey } from '../../dataset/enum/ElementStyle' import { ElementStyleKey } from '../../dataset/enum/ElementStyle'
import { ListStyle, ListType } from '../../dataset/enum/List' import { ListStyle, ListType } from '../../dataset/enum/List'
import { RowFlex } from '../../dataset/enum/Row' import { RowFlex } from '../../dataset/enum/Row'
import { TableBorder } from '../../dataset/enum/table/Table' import { TableBorder, TdBorder } from '../../dataset/enum/table/Table'
import { TitleLevel } from '../../dataset/enum/Title' import { TitleLevel } from '../../dataset/enum/Title'
import { VerticalAlign } from '../../dataset/enum/VerticalAlign' import { VerticalAlign } from '../../dataset/enum/VerticalAlign'
import { ICatalog } from '../../interface/Catalog' import { ICatalog } from '../../interface/Catalog'
@ -1227,6 +1227,27 @@ export class CommandAdapt {
}) })
} }
public tableTdBorderType(payload: TdBorder) {
const isReadonly = this.draw.isReadonly()
if (isReadonly) return
const rowCol = this.draw.getTableParticle().getRangeRowCol()
if (!rowCol) return
const tdList = rowCol.flat()
// 存在则设置边框类型,否则取消设置
const isSetBorderType = tdList.some(td => td.borderType !== payload)
tdList.forEach(td => {
if (isSetBorderType) {
td.borderType = payload
} else {
delete td.borderType
}
})
const { endIndex } = this.range.getRange()
this.draw.render({
curIndex: endIndex
})
}
public tableTdBackgroundColor(payload: string) { public tableTdBackgroundColor(payload: string) {
const isReadonly = this.draw.isReadonly() const isReadonly = this.draw.isReadonly()
if (isReadonly) return if (isReadonly) return

@ -1,5 +1,5 @@
import { VerticalAlign } from '../../../dataset/enum/VerticalAlign' import { VerticalAlign } from '../../../dataset/enum/VerticalAlign'
import { TableBorder } from '../../../dataset/enum/table/Table' import { TableBorder, TdBorder } from '../../../dataset/enum/table/Table'
import { IRegisterContextMenu } from '../../../interface/contextmenu/ContextMenu' import { IRegisterContextMenu } from '../../../interface/contextmenu/ContextMenu'
import { Command } from '../../command/Command' import { Command } from '../../command/Command'
@ -37,6 +37,21 @@ export const tableMenus: IRegisterContextMenu[] = [
callback: (command: Command) => { callback: (command: Command) => {
command.executeTableBorderType(TableBorder.EXTERNAL) command.executeTableBorderType(TableBorder.EXTERNAL)
} }
},
{
i18nPath: 'contextmenu.table.borderTd',
icon: 'border-td',
when: () => true,
childMenus: [
{
i18nPath: 'contextmenu.table.borderTdBottom',
icon: 'border-td-bottom',
when: () => true,
callback: (command: Command) => {
command.executeTableTdBorderType(TdBorder.BOTTOM)
}
}
]
} }
] ]
}, },

@ -1,4 +1,5 @@
import { ElementType, IElement, TableBorder } from '../../../..' import { ElementType, IElement, TableBorder } from '../../../..'
import { TdBorder } from '../../../../dataset/enum/table/Table'
import { IEditorOption } from '../../../../interface/Editor' import { IEditorOption } from '../../../../interface/Editor'
import { ITd } from '../../../../interface/table/Td' import { ITd } from '../../../../interface/table/Td'
import { ITr } from '../../../../interface/table/Tr' import { ITr } from '../../../../interface/table/Tr'
@ -122,40 +123,55 @@ export class TableParticle {
startY: number startY: number
) { ) {
const { colgroup, trList, borderType } = element const { colgroup, trList, borderType } = element
if (!colgroup || !trList || borderType === TableBorder.EMPTY) return if (!colgroup || !trList) return
const { scale } = this.options const { scale } = this.options
const tableWidth = element.width! * scale const tableWidth = element.width! * scale
const tableHeight = element.height! * scale const tableHeight = element.height! * scale
// 无边框
const isEmptyBorderType = borderType === TableBorder.EMPTY
// 仅外边框
const isExternalBorderType = borderType === TableBorder.EXTERNAL const isExternalBorderType = borderType === TableBorder.EXTERNAL
ctx.save() ctx.save()
// 渲染边框 // 渲染边框
this._drawOuterBorder({ if (!isEmptyBorderType) {
ctx, this._drawOuterBorder({
startX, ctx,
startY, startX,
width: tableWidth, startY,
height: tableHeight, width: tableWidth,
isDrawFullBorder: isExternalBorderType height: tableHeight,
}) isDrawFullBorder: isExternalBorderType
if (!isExternalBorderType) { })
// 渲染表格 }
for (let t = 0; t < trList.length; t++) { // 渲染单元格
const tr = trList[t] for (let t = 0; t < trList.length; t++) {
for (let d = 0; d < tr.tdList.length; d++) { const tr = trList[t]
const td = tr.tdList[d] for (let d = 0; d < tr.tdList.length; d++) {
const width = td.width! * scale const td = tr.tdList[d]
const height = td.height! * scale // 没有设置单元格边框 && 没有设置表格边框则忽略
const x = Math.round(td.x! * scale + startX + width) if (!td.borderType && (isEmptyBorderType || isExternalBorderType)) {
const y = Math.round(td.y! * scale + startY) continue
ctx.translate(0.5, 0.5) }
// 绘制线条 const width = td.width! * scale
ctx.beginPath() const height = td.height! * scale
const x = Math.round(td.x! * scale + startX + width)
const y = Math.round(td.y! * scale + startY)
ctx.translate(0.5, 0.5)
// 绘制线条
ctx.beginPath()
if (td.borderType === TdBorder.BOTTOM) {
ctx.moveTo(x, y + height)
ctx.lineTo(x - width, y + height)
ctx.stroke()
}
if (!isEmptyBorderType && !isExternalBorderType) {
ctx.moveTo(x, y + height)
ctx.moveTo(x, y) ctx.moveTo(x, y)
ctx.lineTo(x, y + height) ctx.lineTo(x, y + height)
ctx.lineTo(x - width, y + height) ctx.lineTo(x - width, y + height)
ctx.stroke() ctx.stroke()
ctx.translate(-0.5, -0.5)
} }
ctx.translate(-0.5, -0.5)
} }
} }
ctx.restore() ctx.restore()

@ -43,7 +43,9 @@
"border": "Table border", "border": "Table border",
"borderAll": "All", "borderAll": "All",
"borderEmpty": "Empty", "borderEmpty": "Empty",
"borderExternal": "External" "borderExternal": "External",
"borderTd": "Table cell border",
"borderTdBottom": "Bottom"
} }
}, },
"datePicker": { "datePicker": {

@ -43,7 +43,9 @@
"border": "表格边框", "border": "表格边框",
"borderAll": "所有框线", "borderAll": "所有框线",
"borderEmpty": "无框线", "borderEmpty": "无框线",
"borderExternal": "外侧框线" "borderExternal": "外侧框线",
"borderTd": "单元格边框",
"borderTdBottom": "下边框"
} }
}, },
"datePicker": { "datePicker": {

@ -1,5 +1,6 @@
import { ElementType } from '../enum/Element' import { ElementType } from '../enum/Element'
import { IElement } from '../../interface/Element' import { IElement } from '../../interface/Element'
import { ITd } from '../../interface/table/Td'
export const EDITOR_ELEMENT_STYLE_ATTR: Array<keyof IElement> = [ export const EDITOR_ELEMENT_STYLE_ATTR: Array<keyof IElement> = [
'bold', 'bold',
@ -61,6 +62,12 @@ export const EDITOR_ELEMENT_ZIP_ATTR: Array<keyof IElement> = [
'groupIds' 'groupIds'
] ]
export const TABLE_TD_ZIP_ATTR: Array<keyof ITd> = [
'verticalAlign',
'backgroundColor',
'borderType'
]
export const TABLE_CONTEXT_ATTR: Array<keyof IElement> = [ export const TABLE_CONTEXT_ATTR: Array<keyof IElement> = [
'tdId', 'tdId',
'trId', 'trId',

@ -3,3 +3,7 @@ export enum TableBorder {
EMPTY = 'empty', EMPTY = 'empty',
EXTERNAL = 'external' EXTERNAL = 'external'
} }
export enum TdBorder {
BOTTOM = 'bottom'
}

@ -44,7 +44,7 @@ import { defaultCursorOption } from './dataset/constant/Cursor'
import { IPageNumber } from './interface/PageNumber' import { IPageNumber } from './interface/PageNumber'
import { defaultPageNumberOption } from './dataset/constant/PageNumber' import { defaultPageNumberOption } from './dataset/constant/PageNumber'
import { VerticalAlign } from './dataset/enum/VerticalAlign' import { VerticalAlign } from './dataset/enum/VerticalAlign'
import { TableBorder } from './dataset/enum/table/Table' import { TableBorder, TdBorder } from './dataset/enum/table/Table'
import { IFooter } from './interface/Footer' import { IFooter } from './interface/Footer'
import { defaultFooterOption } from './dataset/constant/Footer' import { defaultFooterOption } from './dataset/constant/Footer'
import { MaxHeightRatio, NumberType } from './dataset/enum/Common' import { MaxHeightRatio, NumberType } from './dataset/enum/Common'
@ -259,6 +259,7 @@ export {
BlockType, BlockType,
PaperDirection, PaperDirection,
TableBorder, TableBorder,
TdBorder,
MaxHeightRatio, MaxHeightRatio,
NumberType, NumberType,
TitleLevel, TitleLevel,

@ -1,4 +1,5 @@
import { VerticalAlign } from '../../dataset/enum/VerticalAlign' import { VerticalAlign } from '../../dataset/enum/VerticalAlign'
import { TdBorder } from '../../dataset/enum/table/Table'
import { IElement, IElementPosition } from '../Element' import { IElement, IElementPosition } from '../Element'
import { IRow } from '../Row' import { IRow } from '../Row'
@ -20,6 +21,7 @@ export interface ITd {
positionList?: IElementPosition[] positionList?: IElementPosition[]
verticalAlign?: VerticalAlign verticalAlign?: VerticalAlign
backgroundColor?: string backgroundColor?: string
borderType?: TdBorder
mainHeight?: number // 内容 + 内边距高度 mainHeight?: number // 内容 + 内边距高度
realHeight?: number // 真实高度(包含跨列) realHeight?: number // 真实高度(包含跨列)
realMinHeight?: number // 真实最小高度(包含跨列) realMinHeight?: number // 真实最小高度(包含跨列)

@ -14,6 +14,7 @@ import {
EDITOR_ELEMENT_ZIP_ATTR, EDITOR_ELEMENT_ZIP_ATTR,
INLINE_NODE_NAME, INLINE_NODE_NAME,
TABLE_CONTEXT_ATTR, TABLE_CONTEXT_ATTR,
TABLE_TD_ZIP_ATTR,
TEXTLIKE_ELEMENT_TYPE TEXTLIKE_ELEMENT_TYPE
} from '../dataset/constant/Element' } from '../dataset/constant/Element'
import { import {
@ -483,12 +484,13 @@ export function zipElementList(payload: IElement[]): IElement[] {
rowspan: td.rowspan, rowspan: td.rowspan,
value: zipElementList(td.value) value: zipElementList(td.value)
} }
if (td.verticalAlign) { // 压缩单元格属性
zipTd.verticalAlign = td.verticalAlign TABLE_TD_ZIP_ATTR.forEach(attr => {
} const value = td[attr] as never
if (td.backgroundColor) { if (value !== undefined) {
zipTd.backgroundColor = td.backgroundColor zipTd[attr] = value
} }
})
tr.tdList[d] = zipTd tr.tdList[d] = zipTd
} }
} }

Loading…
Cancel
Save