feat: table header appears repeatedly when paging #541
Co-authored-by: Hufe921 <huangyunfeihufe@hotmail.com>
This commit is contained in:
@@ -771,6 +771,7 @@ export class CommandAdapt {
|
||||
if (activeControl) return
|
||||
const { startIndex, endIndex } = this.range.getRange()
|
||||
if (!~startIndex && !~endIndex) return
|
||||
const { defaultTrMinHeight } = this.options.table
|
||||
const elementList = this.draw.getElementList()
|
||||
let offsetX = 0
|
||||
if (elementList[startIndex]?.listId) {
|
||||
@@ -794,7 +795,7 @@ export class CommandAdapt {
|
||||
for (let r = 0; r < row; r++) {
|
||||
const tdList: ITd[] = []
|
||||
const tr: ITr = {
|
||||
height: this.options.defaultTrMinHeight,
|
||||
height: defaultTrMinHeight,
|
||||
tdList
|
||||
}
|
||||
for (let c = 0; c < col; c++) {
|
||||
@@ -992,7 +993,7 @@ export class CommandAdapt {
|
||||
// 重新计算宽度
|
||||
const colgroup = element.colgroup!
|
||||
colgroup.splice(curTdIndex, 0, {
|
||||
width: this.options.defaultColMinWidth
|
||||
width: this.options.table.defaultColMinWidth
|
||||
})
|
||||
const colgroupWidth = colgroup.reduce((pre, cur) => pre + cur.width, 0)
|
||||
const width = this.draw.getOriginalInnerWidth()
|
||||
@@ -1051,7 +1052,7 @@ export class CommandAdapt {
|
||||
// 重新计算宽度
|
||||
const colgroup = element.colgroup!
|
||||
colgroup.splice(curTdIndex, 0, {
|
||||
width: this.options.defaultColMinWidth
|
||||
width: this.options.table.defaultColMinWidth
|
||||
})
|
||||
const colgroupWidth = colgroup.reduce((pre, cur) => pre + cur.width, 0)
|
||||
const width = this.draw.getOriginalInnerWidth()
|
||||
|
||||
@@ -398,7 +398,10 @@ export class Draw {
|
||||
}
|
||||
|
||||
public getTdPadding(): IPadding {
|
||||
const { tdPadding, scale } = this.options
|
||||
const {
|
||||
table: { tdPadding },
|
||||
scale
|
||||
} = this.options
|
||||
return <IPadding>tdPadding.map(m => m * scale)
|
||||
}
|
||||
|
||||
@@ -1124,8 +1127,13 @@ export class Draw {
|
||||
|
||||
public computeRowList(payload: IComputeRowListPayload) {
|
||||
const { innerWidth, elementList, isPagingMode = false } = payload
|
||||
const { defaultSize, defaultRowMargin, scale, tdPadding, defaultTabWidth } =
|
||||
this.options
|
||||
const {
|
||||
defaultSize,
|
||||
defaultRowMargin,
|
||||
scale,
|
||||
table: { tdPadding },
|
||||
defaultTabWidth
|
||||
} = this.options
|
||||
const defaultBasicRowMarginHeight = this.getDefaultBasicRowMarginHeight()
|
||||
const canvas = document.createElement('canvas')
|
||||
const ctx = canvas.getContext('2d') as CanvasRenderingContext2D
|
||||
@@ -1214,7 +1222,10 @@ export class Draw {
|
||||
while (tableIndex < elementList.length) {
|
||||
const nextElement = elementList[tableIndex]
|
||||
if (nextElement.pagingId === element.pagingId) {
|
||||
element.trList!.push(...nextElement.trList!)
|
||||
const nexTrList = nextElement.trList!.filter(
|
||||
tr => !tr.pagingRepeat
|
||||
)
|
||||
element.trList!.push(...nexTrList)
|
||||
element.height! += nextElement.height!
|
||||
tableIndex++
|
||||
combineCount++
|
||||
@@ -1226,6 +1237,7 @@ export class Draw {
|
||||
elementList.splice(i + 1, combineCount)
|
||||
}
|
||||
}
|
||||
element.pagingIndex = element.pagingIndex ?? 0
|
||||
// 计算表格行列
|
||||
this.tableParticle.computeRowColInfo(element)
|
||||
// 计算表格内元素信息
|
||||
@@ -1323,11 +1335,12 @@ export class Draw {
|
||||
curPagePreHeight += row.height
|
||||
}
|
||||
}
|
||||
// 当前剩余高度是否能容下当前表格第一行(可拆分)的高度
|
||||
// 当前剩余高度是否能容下当前表格第一行(可拆分)的高度,排除掉表头类型
|
||||
const rowMarginHeight = rowMargin * 2 * scale
|
||||
if (
|
||||
curPagePreHeight + element.trList![0].height! + rowMarginHeight >
|
||||
height
|
||||
height ||
|
||||
(element.pagingIndex !== 0 && element.trList![0].pagingRepeat)
|
||||
) {
|
||||
// 无可拆分行则切换至新页
|
||||
curPagePreHeight = marginHeight
|
||||
@@ -1378,6 +1391,14 @@ export class Draw {
|
||||
// 追加拆分表格
|
||||
const cloneElement = deepClone(element)
|
||||
cloneElement.pagingId = pagingId
|
||||
cloneElement.pagingIndex = element.pagingIndex! + 1
|
||||
// 处理分页重复表头
|
||||
const repeatTrList = trList.filter(tr => tr.pagingRepeat)
|
||||
if (repeatTrList.length) {
|
||||
const cloneRepeatTrList = deepClone(repeatTrList)
|
||||
cloneRepeatTrList.forEach(tr => (tr.id = getUUID()))
|
||||
cloneTrList.unshift(...cloneRepeatTrList)
|
||||
}
|
||||
cloneElement.trList = cloneTrList
|
||||
cloneElement.id = getUUID()
|
||||
this.spliceElementList(elementList, i + 1, 0, cloneElement)
|
||||
@@ -1742,7 +1763,12 @@ export class Draw {
|
||||
// 优先绘制高亮元素
|
||||
this._drawHighlight(ctx, payload)
|
||||
// 绘制元素、下划线、删除线、选区
|
||||
const { scale, tdPadding, group, lineBreak } = this.options
|
||||
const {
|
||||
scale,
|
||||
table: { tdPadding },
|
||||
group,
|
||||
lineBreak
|
||||
} = this.options
|
||||
const {
|
||||
rowList,
|
||||
pageNo,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { IElement } from '../../../..'
|
||||
import { EDITOR_PREFIX } from '../../../../dataset/constant/Editor'
|
||||
import { TableOrder } from '../../../../dataset/enum/table/TableTool'
|
||||
import { DeepRequired } from '../../../../interface/Common'
|
||||
import { IEditorOption } from '../../../../interface/Editor'
|
||||
import { Position } from '../../../position/Position'
|
||||
import { Draw } from '../../Draw'
|
||||
@@ -22,7 +23,7 @@ export class TableTool {
|
||||
|
||||
private draw: Draw
|
||||
private canvas: HTMLCanvasElement
|
||||
private options: Required<IEditorOption>
|
||||
private options: DeepRequired<IEditorOption>
|
||||
private position: Position
|
||||
private container: HTMLDivElement
|
||||
private toolRowContainer: HTMLDivElement | null
|
||||
@@ -255,7 +256,7 @@ export class TableTool {
|
||||
const trList = element.trList!
|
||||
const tr = trList[index] || trList[index - 1]
|
||||
// 最大移动高度-向上移动超出最小高度限定,则减少移动量
|
||||
const { defaultTrMinHeight } = this.options
|
||||
const { defaultTrMinHeight } = this.options.table
|
||||
if (dy < 0 && tr.height + dy < defaultTrMinHeight) {
|
||||
dy = defaultTrMinHeight - tr.height
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import { Draw } from '../draw/Draw'
|
||||
import { EditorMode, EditorZone } from '../../dataset/enum/Editor'
|
||||
import { deepClone } from '../../utils'
|
||||
import { ImageDisplay } from '../../dataset/enum/Common'
|
||||
import { DeepRequired } from '../../interface/Common'
|
||||
|
||||
export class Position {
|
||||
private cursorPosition: IElementPosition | null
|
||||
@@ -27,7 +28,7 @@ export class Position {
|
||||
private floatPositionList: IFloatPosition[]
|
||||
|
||||
private draw: Draw
|
||||
private options: Required<IEditorOption>
|
||||
private options: DeepRequired<IEditorOption>
|
||||
|
||||
constructor(draw: Draw) {
|
||||
this.positionList = []
|
||||
@@ -114,7 +115,10 @@ export class Position {
|
||||
innerWidth,
|
||||
zone
|
||||
} = payload
|
||||
const { scale, tdPadding } = this.options
|
||||
const {
|
||||
scale,
|
||||
table: { tdPadding }
|
||||
} = this.options
|
||||
let x = startX
|
||||
let y = startY
|
||||
let index = startIndex
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import { ITableOption } from '../../interface/table/Table'
|
||||
|
||||
export const defaultTableOption: Readonly<Required<ITableOption>> = {
|
||||
tdPadding: [0, 5, 5, 5],
|
||||
defaultTrMinHeight: 42,
|
||||
defaultColMinWidth: 40
|
||||
}
|
||||
+7
-3
@@ -82,6 +82,8 @@ import { ILineBreakOption } from './interface/LineBreak'
|
||||
import { defaultLineBreak } from './dataset/constant/LineBreak'
|
||||
import { ISeparatorOption } from './interface/Separator'
|
||||
import { defaultSeparatorOption } from './dataset/constant/Separator'
|
||||
import { ITableOption } from './interface/table/Table'
|
||||
import { defaultTableOption } from './dataset/constant/Table'
|
||||
|
||||
export default class Editor {
|
||||
public command: Command
|
||||
@@ -97,6 +99,10 @@ export default class Editor {
|
||||
data: IEditorData | IElement[],
|
||||
options: IEditorOption = {}
|
||||
) {
|
||||
const tableOptions: Required<ITableOption> = {
|
||||
...defaultTableOption,
|
||||
...options.table
|
||||
}
|
||||
const headerOptions: Required<IHeader> = {
|
||||
...defaultHeaderOption,
|
||||
...options.header
|
||||
@@ -192,9 +198,6 @@ export default class Editor {
|
||||
marginIndicatorColor: '#BABABA',
|
||||
margins: [100, 120, 100, 120],
|
||||
pageMode: PageMode.PAGING,
|
||||
tdPadding: [0, 5, 5, 5],
|
||||
defaultTrMinHeight: 42,
|
||||
defaultColMinWidth: 40,
|
||||
defaultHyperlinkColor: '#0000FF',
|
||||
paperDirection: PaperDirection.VERTICAL,
|
||||
inactiveAlpha: 0.6,
|
||||
@@ -206,6 +209,7 @@ export default class Editor {
|
||||
contextMenuDisableKeys: [],
|
||||
scrollContainerSelector: '',
|
||||
...options,
|
||||
table: tableOptions,
|
||||
header: headerOptions,
|
||||
footer: footerOptions,
|
||||
pageNumber: pageNumberOptions,
|
||||
|
||||
@@ -8,7 +8,6 @@ import {
|
||||
import { IBackgroundOption } from './Background'
|
||||
import { ICheckboxOption } from './Checkbox'
|
||||
import { IRadioOption } from './Radio'
|
||||
import { IPadding } from './Common'
|
||||
import { IControlOption } from './Control'
|
||||
import { ICursorOption } from './Cursor'
|
||||
import { IFooter } from './Footer'
|
||||
@@ -23,6 +22,7 @@ import { ITitleOption } from './Title'
|
||||
import { IWatermark } from './Watermark'
|
||||
import { IZoneOption } from './Zone'
|
||||
import { ISeparatorOption } from './Separator'
|
||||
import { ITableOption } from './table/Table'
|
||||
|
||||
export interface IEditorData {
|
||||
header?: IElement[]
|
||||
@@ -60,9 +60,6 @@ export interface IEditorOption {
|
||||
marginIndicatorColor?: string
|
||||
margins?: IMargin
|
||||
pageMode?: PageMode
|
||||
tdPadding?: IPadding
|
||||
defaultTrMinHeight?: number
|
||||
defaultColMinWidth?: number
|
||||
defaultHyperlinkColor?: string
|
||||
paperDirection?: PaperDirection
|
||||
inactiveAlpha?: number
|
||||
@@ -73,6 +70,7 @@ export interface IEditorOption {
|
||||
contextMenuDisableKeys?: string[]
|
||||
scrollContainerSelector?: string
|
||||
wordBreak?: WordBreak
|
||||
table?: ITableOption
|
||||
header?: IHeader
|
||||
footer?: IFooter
|
||||
pageNumber?: IPageNumber
|
||||
|
||||
@@ -69,6 +69,7 @@ export interface ITableElement {
|
||||
tableId?: string
|
||||
conceptId?: string
|
||||
pagingId?: string // 用于区分拆分的表格同属一个源表格
|
||||
pagingIndex?: number // 拆分的表格索引
|
||||
}
|
||||
|
||||
export type ITable = ITableAttr & ITableElement
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import { IPadding } from '../Common'
|
||||
|
||||
export interface ITableOption {
|
||||
tdPadding?: IPadding
|
||||
defaultTrMinHeight?: number
|
||||
defaultColMinWidth?: number
|
||||
}
|
||||
@@ -5,4 +5,5 @@ export interface ITr {
|
||||
height: number
|
||||
tdList: ITd[]
|
||||
minHeight?: number
|
||||
pagingRepeat?: boolean // 在各页顶端以标题行的形式重复出现
|
||||
}
|
||||
|
||||
@@ -148,15 +148,13 @@ export function formatElementList(
|
||||
const tableId = getUUID()
|
||||
el.id = tableId
|
||||
if (el.trList) {
|
||||
const { defaultTrMinHeight } = editorOptions.table
|
||||
for (let t = 0; t < el.trList.length; t++) {
|
||||
const tr = el.trList[t]
|
||||
const trId = getUUID()
|
||||
tr.id = trId
|
||||
if (
|
||||
!tr.minHeight ||
|
||||
tr.minHeight < editorOptions.defaultTrMinHeight
|
||||
) {
|
||||
tr.minHeight = editorOptions.defaultTrMinHeight
|
||||
if (!tr.minHeight || tr.minHeight < defaultTrMinHeight) {
|
||||
tr.minHeight = defaultTrMinHeight
|
||||
}
|
||||
if (tr.height < tr.minHeight) {
|
||||
tr.height = tr.minHeight
|
||||
|
||||
Reference in New Issue
Block a user