|
|
@@ -161,6 +161,7 @@ const loading = ref(true)
|
|
|
const showSpread=ref(true)
|
|
|
const previewContainer = ref(null)
|
|
|
let sheetData = {};
|
|
|
+let arrayFieldOffsetInfos = [];
|
|
|
const designerKey = import.meta.env.VITE_SPREADJS_DESIGNER_KEY
|
|
|
const nodeEnv = import.meta.env.VITE_NODE_ENV
|
|
|
const licenseKey = import.meta.env.VITE_SPREADJS_LICENSE_KEY
|
|
|
@@ -245,7 +246,8 @@ const initPreview = async () => {
|
|
|
const res = await initCommonData();
|
|
|
|
|
|
// 2. 调用后端接口获取处理好的 SJS
|
|
|
- const apiMethod = nodeEnv === 'dev' ? ExcelApi.process : ExcelApi.excel;
|
|
|
+ const apiMethod = ExcelApi.excel;
|
|
|
+ // const apiMethod = nodeEnv === 'dev' ? ExcelApi.process : ExcelApi.excel;
|
|
|
const sjsBlob: any = await apiMethod({ templateId, refId });
|
|
|
|
|
|
// 3. 打开 SJS 后在回调中绑定数据源
|
|
|
@@ -513,26 +515,90 @@ const selectWingdings = (item) => {
|
|
|
const handleSave = () => {
|
|
|
loading.value = true;
|
|
|
let dataSource = {};
|
|
|
+
|
|
|
+ const allSheetsData = []
|
|
|
previewSpread.sheets.forEach((sheet) => {
|
|
|
if (sheet.name() && sheet.name() !== '试用版警告') {
|
|
|
- // 收集 sheet 的数据源(兼容 table 绑定字段)
|
|
|
const sheetData = collectSheetDataSource(sheet);
|
|
|
- console.log(sheetData)
|
|
|
- for (const key in sheetData) {
|
|
|
- if (dataSource[key] && sheetData[key] == sheetData[key]) {
|
|
|
- } else {
|
|
|
- dataSource[key] = sheetData[key];
|
|
|
+ const pageNo = getPageNoFromSheet(sheet);
|
|
|
+ allSheetsData.push({ pageNo, data: sheetData, sheet });
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ let copyRangePathSet = new Set();
|
|
|
+ const hasContinuationPages = allSheetsData.some(({ pageNo }) => pageNo > 1);
|
|
|
+ let pageNoBindingPath = null
|
|
|
+ if (hasContinuationPages && generateData && generateData.copyRange) {
|
|
|
+ const rangeInfo = getCopyRangeInfo();
|
|
|
+ const templateSheet = previewSpread.getSheetFromName(generateData.sheetName);
|
|
|
+ if (templateSheet && rangeInfo) {
|
|
|
+ getCopyRangeBindingPaths(templateSheet, rangeInfo).forEach(p => copyRangePathSet.add(p));
|
|
|
+ pageNoBindingPath = templateSheet.getBindingPath(rangeInfo.row, rangeInfo.col)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (const { pageNo, data, sheet } of allSheetsData) {
|
|
|
+ for (const key in data) {
|
|
|
+ if (pageNo > 1 && key === pageNoBindingPath) continue
|
|
|
+ if (arrayFieldOffsetInfos.some(oi => key.startsWith(oi.prefix + '_'))) continue
|
|
|
+ if (hasContinuationPages && copyRangePathSet.has(key)) {
|
|
|
+ if (!dataSource[key]) {
|
|
|
+ dataSource[key] = [];
|
|
|
+ }
|
|
|
+ if (Array.isArray(dataSource[key])) {
|
|
|
+ while (dataSource[key].length < pageNo) {
|
|
|
+ dataSource[key].push(null);
|
|
|
+ }
|
|
|
+ dataSource[key][pageNo - 1] = data[key];
|
|
|
+ }
|
|
|
+ } else if (hasContinuationPages && Array.isArray(sheetData?.[key]) && !arrayFieldOffsetInfos.some(oi => key === oi.prefix)) {
|
|
|
+ if (!dataSource[key]) {
|
|
|
+ dataSource[key] = [];
|
|
|
+ }
|
|
|
+ if (Array.isArray(data[key])) {
|
|
|
+ dataSource[key] = dataSource[key].concat(data[key]);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (!dataSource.hasOwnProperty(key) && data[key] != null) {
|
|
|
+ dataSource[key] = data[key];
|
|
|
}
|
|
|
}
|
|
|
- // 收集形状(浮动图片)数据
|
|
|
- collectShapesIntoDataSource(sheet, dataSource);
|
|
|
}
|
|
|
- });
|
|
|
+ collectShapesIntoDataSource(sheet, dataSource);
|
|
|
+ }
|
|
|
+
|
|
|
+ for (const oi of arrayFieldOffsetInfos) {
|
|
|
+ const { prefix, fields } = oi
|
|
|
+ const copyMinIndex = Math.min(...fields.map(f => f.index))
|
|
|
+ const copyFieldNames = new Set(fields.map(f => f.path))
|
|
|
+ const result = []
|
|
|
+ const templateSheetData = allSheetsData.find(s => s.sheet.name() === generateData.sheetName)
|
|
|
+ if (templateSheetData) {
|
|
|
+ for (let i = 1; i < copyMinIndex; i++) {
|
|
|
+ const fieldName = `${prefix}_${i}`
|
|
|
+ if (!copyFieldNames.has(fieldName)) {
|
|
|
+ const val = templateSheetData.data[fieldName]
|
|
|
+ if (val != null) {
|
|
|
+ result.push(Array.isArray(val) ? val[0] || null : val)
|
|
|
+ } else {
|
|
|
+ result.push(null)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (const { data, sheet } of allSheetsData) {
|
|
|
+ if (sheet.name() !== generateData.sheetName && !sheet.name().startsWith(generateData.sheetName + ' (')) continue
|
|
|
+ for (const f of fields) {
|
|
|
+ result.push(data[f.path] != null ? data[f.path] : null)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ dataSource[`${prefix}_1`] = result
|
|
|
+ }
|
|
|
+
|
|
|
if (Object.keys(dataSource).length > 0) {
|
|
|
- // 序列化为后端存储格式(对象/数组 → JSON 字符串)
|
|
|
const serializedData = serializeDataSourceForStorage(dataSource);
|
|
|
console.log(serializedData);
|
|
|
-
|
|
|
+
|
|
|
DynamicTbValApi.saveAllColValue(insId.value, serializedData).then(res => {
|
|
|
if (res) {
|
|
|
ElMessage.success('保存成功')
|
|
|
@@ -552,6 +618,23 @@ const handleSave = () => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+const distributePageDataSources = () => {
|
|
|
+ if (!generateData || !generateData.copyRange) return
|
|
|
+ previewSpread.sheets.forEach((sheet) => {
|
|
|
+ if (sheet.name() && sheet.name() !== '试用版警告' && sheet.name() !== generateData.sheetName) {
|
|
|
+ const pageNo = getPageNoFromSheet(sheet)
|
|
|
+ if (pageNo > 1 && sheetData && Object.keys(sheetData).length > 0) {
|
|
|
+ const pageData = buildPageDataSource(sheetData, pageNo)
|
|
|
+ const dataSource = new GC.Spread.Sheets.Bindings.CellBindingSource(pageData)
|
|
|
+ sheet.setDataSource(dataSource)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
const handleCopyRow = () => {
|
|
|
if (!previewSpread) return ElMessage.warning('请先加载文档')
|
|
|
const activeSheet = previewSpread.getActiveSheet()
|
|
|
@@ -613,6 +696,238 @@ const close = () => {
|
|
|
emit('close')
|
|
|
}
|
|
|
|
|
|
+const getPageNoFromSheet = (sheet) => {
|
|
|
+ const tag = sheet.tag()
|
|
|
+ if (tag !== undefined && tag !== null && tag !== '' && !isNaN(parseInt(tag))) {
|
|
|
+ return parseInt(tag)
|
|
|
+ }
|
|
|
+ const name = sheet.name()
|
|
|
+ const match = name.match(/\((\d+)\)\s*$/)
|
|
|
+ if (match) {
|
|
|
+ return parseInt(match[1])
|
|
|
+ }
|
|
|
+ return 1
|
|
|
+}
|
|
|
+
|
|
|
+const getCopyRangeInfo = () => {
|
|
|
+ if (!generateData || !generateData.copyRange) return null
|
|
|
+ const col = parseInt(generateData.copyRange.topLeft.split(',')[0])
|
|
|
+ const row = parseInt(generateData.copyRange.topLeft.split(',')[1])
|
|
|
+ const colCount = parseInt(generateData.copyRange.topRight.split(',')[0]) - col
|
|
|
+ const rowCount = parseInt(generateData.copyRange.bottomLeft.split(',')[1]) - row
|
|
|
+ return { col, row, colCount, rowCount }
|
|
|
+}
|
|
|
+
|
|
|
+const getCopyRangeBindingPaths = (sheet, rangeInfo) => {
|
|
|
+ if (!sheet || !rangeInfo) return []
|
|
|
+ const { col, row, colCount, rowCount } = rangeInfo
|
|
|
+ const paths = []
|
|
|
+ for (let i = 0; i <= colCount; i++) {
|
|
|
+ for (let j = 0; j <= rowCount; j++) {
|
|
|
+ const bindingPath = sheet.getBindingPath(row + j, col + i)
|
|
|
+ if (bindingPath) {
|
|
|
+ paths.push(bindingPath)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return paths
|
|
|
+}
|
|
|
+
|
|
|
+const buildPageDataSource = (baseData, pageNo) => {
|
|
|
+ if (!generateData || !generateData.copyRange) return baseData
|
|
|
+ const rangeInfo = getCopyRangeInfo()
|
|
|
+ if (!rangeInfo) return baseData
|
|
|
+ const sheet = previewSpread.getSheetFromName(generateData.sheetName)
|
|
|
+ if (!sheet) return baseData
|
|
|
+ const pageData = { ...baseData }
|
|
|
+ const bindingPaths = getCopyRangeBindingPaths(sheet, rangeInfo)
|
|
|
+ const bindingPathSet = new Set(bindingPaths)
|
|
|
+ for (const path of bindingPaths) {
|
|
|
+ const val = baseData[path]
|
|
|
+ if (Array.isArray(val)) {
|
|
|
+ pageData[path] = val[pageNo - 1] !== undefined ? val[pageNo - 1] : null
|
|
|
+ } else if (pageNo > 1) {
|
|
|
+ pageData[path] = null
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const rowsPerPage = rangeInfo.rowCount + 1
|
|
|
+ for (const key in baseData) {
|
|
|
+ if (bindingPathSet.has(key)) continue
|
|
|
+ const val = baseData[key]
|
|
|
+ if (Array.isArray(val)) {
|
|
|
+ const start = (pageNo - 1) * rowsPerPage
|
|
|
+ pageData[key] = val.slice(start, start + rowsPerPage)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (const oi of arrayFieldOffsetInfos) {
|
|
|
+ const { fullArray, fields } = oi
|
|
|
+ const copyMinIndex = Math.min(...fields.map(f => f.index))
|
|
|
+ const start = (copyMinIndex - 1) + (pageNo - 1) * oi.rowsPerPage
|
|
|
+ let firstIdx = -1, lastIdx = -1
|
|
|
+ let firstVal = undefined
|
|
|
+ for (const f of fields) {
|
|
|
+ const idx = start + (f.index - copyMinIndex)
|
|
|
+ if (firstIdx === -1) { firstIdx = idx; firstVal = idx < fullArray.length ? fullArray[idx] : null }
|
|
|
+ lastIdx = idx
|
|
|
+ pageData[f.path] = idx < fullArray.length ? fullArray[idx] : null
|
|
|
+ }
|
|
|
+ console.log(`[buildPageDataSource] pageNo=${pageNo}, prefix=${oi.prefix}, start=${start}, idxRange=[${firstIdx},${lastIdx}], firstIdxVal=${JSON.stringify(firstVal)}, fullArrayLen=${fullArray.length}, copyMinIndex=${copyMinIndex}, rowsPerPage=${oi.rowsPerPage}`)
|
|
|
+ }
|
|
|
+ return pageData
|
|
|
+}
|
|
|
+
|
|
|
+const distributeArrayFieldToCells = () => {
|
|
|
+ if (!generateData || !generateData.copyRange) {
|
|
|
+ console.log('[distributeArrayFieldToCells] 跳过: generateData/copyRange 为空')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (!sheetData || !Object.keys(sheetData).length) {
|
|
|
+ console.log('[distributeArrayFieldToCells] 跳过: sheetData 为空')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const rangeInfo = getCopyRangeInfo()
|
|
|
+ if (!rangeInfo) {
|
|
|
+ console.log('[distributeArrayFieldToCells] 跳过: rangeInfo 为空')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const baseSheet = previewSpread.getSheetFromName(generateData.sheetName)
|
|
|
+ if (!baseSheet) {
|
|
|
+ console.log('[distributeArrayFieldToCells] 跳过: 找不到基础 sheet')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ const pattern = /^(.+)_(\d+)$/
|
|
|
+ const prefixGroups = {}
|
|
|
+ for (let r = 0; r <= rangeInfo.rowCount; r++) {
|
|
|
+ for (let c = 0; c <= rangeInfo.colCount; c++) {
|
|
|
+ const bp = baseSheet.getBindingPath(rangeInfo.row + r, rangeInfo.col + c)
|
|
|
+ if (bp) {
|
|
|
+ const match = bp.match(pattern)
|
|
|
+ if (match) {
|
|
|
+ const pfx = match[1]
|
|
|
+ if (!prefixGroups[pfx]) prefixGroups[pfx] = []
|
|
|
+ prefixGroups[pfx].push({
|
|
|
+ path: bp, prefix: pfx, index: parseInt(match[2]), rowInRange: r, col: c
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log('[distributeArrayFieldToCells] copyRange 扫描到的前缀组:', Object.keys(prefixGroups))
|
|
|
+
|
|
|
+ arrayFieldOffsetInfos = []
|
|
|
+ const prefixSet = new Set()
|
|
|
+
|
|
|
+ for (const pfx of Object.keys(prefixGroups)) {
|
|
|
+ const fields = prefixGroups[pfx]
|
|
|
+ let fullArray = null
|
|
|
+ for (let i = 0; i <= 1000; i++) {
|
|
|
+ const candidate = `${pfx}_${i}`
|
|
|
+ const val = sheetData[candidate]
|
|
|
+ if (Array.isArray(val) && val.length > 0) {
|
|
|
+ fullArray = val
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!fullArray) {
|
|
|
+ console.log(`[distributeArrayFieldToCells] 前缀 "${pfx}" 未找到数组字段`)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ for (let i = 0; i < fullArray.length; i++) {
|
|
|
+ const key = `${pfx}_${i + 1}`
|
|
|
+ sheetData[key] = fullArray[i]
|
|
|
+ }
|
|
|
+
|
|
|
+ arrayFieldOffsetInfos.push({ prefix: pfx, fullArray, rowsPerPage: rangeInfo.rowCount + 1, fields })
|
|
|
+ prefixSet.add(pfx)
|
|
|
+ console.log(`[distributeArrayFieldToCells] 前缀 "${pfx}" 成功: 数组长度=${fullArray.length}, rowsPerPage=${rangeInfo.rowCount}, copyRange 字段数=${fields.length}`)
|
|
|
+ }
|
|
|
+
|
|
|
+ if (arrayFieldOffsetInfos.length === 0) {
|
|
|
+ console.log('[distributeArrayFieldToCells] 无有效数组,结束')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ previewSpread.suspendPaint()
|
|
|
+ try {
|
|
|
+ const copyStartRow = rangeInfo.row
|
|
|
+ const copyRangeRowSet = new Set()
|
|
|
+ for (let r = 0; r < rangeInfo.rowCount; r++) {
|
|
|
+ copyRangeRowSet.add(copyStartRow + r)
|
|
|
+ }
|
|
|
+ for (const oi of arrayFieldOffsetInfos) {
|
|
|
+ for (const f of oi.fields) {
|
|
|
+ const idx = f.index - 1
|
|
|
+ const cellRow = copyStartRow + f.rowInRange
|
|
|
+ if (idx < oi.fullArray.length) {
|
|
|
+ baseSheet.setValue(cellRow, rangeInfo.col + f.col, oi.fullArray[idx])
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (let r = 0; r < baseSheet.getRowCount(); r++) {
|
|
|
+ if (copyRangeRowSet.has(r)) continue
|
|
|
+ for (let c = 0; c < baseSheet.getColumnCount(); c++) {
|
|
|
+ const bp = baseSheet.getBindingPath(r, c)
|
|
|
+ if (bp) {
|
|
|
+ const match = bp.match(pattern)
|
|
|
+ if (match && prefixSet.has(match[1])) {
|
|
|
+ const idx = parseInt(match[2]) - 1
|
|
|
+ const oi = arrayFieldOffsetInfos.find(o => o.prefix === match[1])
|
|
|
+ if (oi && idx < oi.fullArray.length) {
|
|
|
+ baseSheet.setValue(r, c, oi.fullArray[idx])
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const baseDS = baseSheet.getDataSource()
|
|
|
+ if (baseDS && baseDS.rT) {
|
|
|
+ for (const oi of arrayFieldOffsetInfos) {
|
|
|
+ oi.fullArray.forEach((val, idx) => {
|
|
|
+ baseDS.rT[`${oi.prefix}_${idx + 1}`] = val
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ previewSpread.resumePaint()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const adjustBaseSheetArrays = () => {
|
|
|
+ if (!generateData || !generateData.copyRange || !sheetData || !Object.keys(sheetData).length) return
|
|
|
+ const rangeInfo = getCopyRangeInfo()
|
|
|
+ if (!rangeInfo) return
|
|
|
+ const baseSheet = previewSpread.getSheetFromName(generateData.sheetName)
|
|
|
+ if (!baseSheet) return
|
|
|
+ const bindingPaths = getCopyRangeBindingPaths(baseSheet, rangeInfo)
|
|
|
+ const bindingPathSet = new Set(bindingPaths)
|
|
|
+ const rowsPerPage = rangeInfo.rowCount + 1
|
|
|
+ previewSpread.suspendPaint()
|
|
|
+ try {
|
|
|
+ for (let row = 0; row < baseSheet.getRowCount(); row++) {
|
|
|
+ for (let col = 0; col < baseSheet.getColumnCount(); col++) {
|
|
|
+ const bp = baseSheet.getBindingPath(row, col)
|
|
|
+ if (bp && !bindingPathSet.has(bp) && Array.isArray(sheetData[bp])) {
|
|
|
+ const val = baseSheet.getValue(row, col)
|
|
|
+ if (Array.isArray(val)) {
|
|
|
+ baseSheet.setValue(row, col, val.slice(0, rowsPerPage))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ previewSpread.resumePaint()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const setPageNoToSheet = (sheet, pageNo, rangeInfo) => {
|
|
|
+ if (!rangeInfo) return
|
|
|
+ sheet.tag(String(pageNo))
|
|
|
+}
|
|
|
+
|
|
|
let generateData
|
|
|
let sheetNum = ref(2)
|
|
|
/**
|
|
|
@@ -631,42 +946,53 @@ const handleGenerate = async (isSetTimeout) => {
|
|
|
const generate = async (isAdd) => {
|
|
|
|
|
|
const sheet = previewSpread.getSheetFromName(generateData.sheetName)
|
|
|
- if (sheet.visible()) {
|
|
|
- previewSpread.commandManager().execute({
|
|
|
- cmd: "copySheet",
|
|
|
- sheetName: generateData.sheetName,
|
|
|
- targetIndex: 999,
|
|
|
- newName: generateData.sheetName + " (" + sheetNum.value + ")",
|
|
|
- includeBindingSource: true
|
|
|
- });
|
|
|
- } else {
|
|
|
+ if (!sheet.visible()) {
|
|
|
sheet.visible(true)
|
|
|
- return
|
|
|
}
|
|
|
+ console.log('生成续页',generateData.sheetName + " (" + sheetNum.value + ")");
|
|
|
+
|
|
|
+ previewSpread.commandManager().execute({
|
|
|
+ cmd: "copySheet",
|
|
|
+ sheetName: generateData.sheetName,
|
|
|
+ targetIndex: 999,
|
|
|
+ newName: generateData.sheetName + " (" + sheetNum.value + ")",
|
|
|
+ includeBindingSource: true
|
|
|
+ });
|
|
|
// 范围内的字段叠加
|
|
|
let col = parseInt(generateData.copyRange.topLeft.split(',')[0])
|
|
|
let row = parseInt(generateData.copyRange.topLeft.split(',')[1])
|
|
|
let colCount = parseInt(generateData.copyRange.topRight.split(',')[0]) - col
|
|
|
let rowCount = parseInt(generateData.copyRange.bottomLeft.split(',')[1]) - row
|
|
|
const sheet2 = previewSpread.getSheetFromName(generateData.sheetName + " (" + sheetNum.value + ")")
|
|
|
- let colPathList = []
|
|
|
- let dynamicTbColRespVOListCode = dynamicTbColRespVOList.map(i => i.colCode)
|
|
|
- for (let i = 0; i <= colCount; i++) {
|
|
|
- for (let j = 0; j <= rowCount; j++) {
|
|
|
- const bindingPath = sheet.getBindingPath(row + j, col + i)
|
|
|
- if (bindingPath) {
|
|
|
- let newPath = bindingPath.split('_')[0] + "_" + (parseInt(bindingPath.split('_')[1]) + (rowCount + 1) * (sheetNum.value - 1))
|
|
|
- sheet2.setBindingPath(row + j, col + i, newPath)
|
|
|
- if (!dynamicTbColRespVOListCode.includes(newPath)){
|
|
|
- colPathList.push(newPath)
|
|
|
- }
|
|
|
+ const rangeInfo = getCopyRangeInfo()
|
|
|
+ const pageNo = sheetNum.value
|
|
|
+ sheetNum.value = sheetNum.value + 1
|
|
|
+ // 先设页码(tag 持久化),后续 dataSource 会覆盖左上角单元格为正确数据
|
|
|
+ setPageNoToSheet(sheet2, pageNo, rangeInfo)
|
|
|
+ // 解绑 copySheet 带来的旧数据源,再绑定新数据源,防止旧数据覆盖新值
|
|
|
+ if (sheet2) {
|
|
|
+ sheet2.setDataSource(null)
|
|
|
+ }
|
|
|
+ if (sheet2 && sheetData && Object.keys(sheetData).length > 0) {
|
|
|
+ const pageData = buildPageDataSource(sheetData, pageNo)
|
|
|
+ const dataSource = new GC.Spread.Sheets.Bindings.CellBindingSource(pageData)
|
|
|
+ sheet2.setDataSource(dataSource)
|
|
|
+
|
|
|
+ // 验证:读取续页 copyRange 第一行和最后一行实际单元格值
|
|
|
+ if (rangeInfo) {
|
|
|
+ const firstRowVals = []
|
|
|
+ const lastRowVals = []
|
|
|
+ for (let c = 0; c <= rangeInfo.colCount; c++) {
|
|
|
+ const bp = sheet2.getBindingPath(rangeInfo.row, rangeInfo.col + c)
|
|
|
+ const firstVal = sheet2.getValue(rangeInfo.row, rangeInfo.col + c)
|
|
|
+ const lastVal = sheet2.getValue(rangeInfo.row + rangeInfo.rowCount, rangeInfo.col + c)
|
|
|
+ firstRowVals.push(`${bp || '?'}=${JSON.stringify(firstVal)}`)
|
|
|
+ lastRowVals.push(`${bp || '?'}=${JSON.stringify(lastVal)}`)
|
|
|
}
|
|
|
+ console.log(`[generate] pageNo=${pageNo} 续页第一行:`, firstRowVals.join(' | '))
|
|
|
+ console.log(`[generate] pageNo=${pageNo} 续页最后行:`, lastRowVals.join(' | '))
|
|
|
}
|
|
|
}
|
|
|
- sheetNum.value = sheetNum.value + 1
|
|
|
- if (colPathList.length != 0){
|
|
|
- await DynamicTbColApi.createBatchByCodes(colPathList,props.initData.templateId)
|
|
|
- }
|
|
|
if (isAdd){
|
|
|
let col = parseInt(generateData.copyRange.topLeft.split(',')[0])
|
|
|
let row = parseInt(generateData.copyRange.topLeft.split(',')[1])
|
|
|
@@ -676,9 +1002,9 @@ const handleGenerate = async (isSetTimeout) => {
|
|
|
return;
|
|
|
}
|
|
|
if (generateData.hidden) {
|
|
|
- // 判断第一行,如果全部为空,则隐藏
|
|
|
let isEmpty = true;
|
|
|
- for (let i = 0; i < colCount; i++) {
|
|
|
+ for (let i = 0; i <= colCount; i++) {
|
|
|
+ if (i === 0) continue
|
|
|
const range = sheet2.getCell(row, col + i)
|
|
|
if (range.value()) {
|
|
|
isEmpty = false;
|
|
|
@@ -689,15 +1015,28 @@ const handleGenerate = async (isSetTimeout) => {
|
|
|
sheet2.visible(false)
|
|
|
}
|
|
|
}
|
|
|
- // 判断最后一行,如果不为空,自动续页
|
|
|
let isNotEmpty = false;
|
|
|
- for (let i = 0; i < colCount; i++) {
|
|
|
+ for (let i = 0; i <= colCount; i++) {
|
|
|
const range = sheet2.getCell(row + rowCount, col + i)
|
|
|
if (range.value()) {
|
|
|
isNotEmpty = true;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
+ console.log(`[generate] pageNo=${pageNo} 单元格检测 isNotEmpty=${isNotEmpty} (检查最后行 row=${row + rowCount}, 列范围=[${col},${col + colCount}])`)
|
|
|
+
|
|
|
+ if (!isNotEmpty && arrayFieldOffsetInfos.length > 0) {
|
|
|
+ for (const oi of arrayFieldOffsetInfos) {
|
|
|
+ const copyMinIndex = Math.min(...oi.fields.map(f => f.index))
|
|
|
+ const usedSoFar = (copyMinIndex - 1) + pageNo * oi.rowsPerPage
|
|
|
+ console.log(`[generate] 续页检查 pageNo=${pageNo}, prefix=${oi.prefix}, usedSoFar=${usedSoFar}, fullArrayLen=${oi.fullArray.length}, 是否需续页=${oi.fullArray.length > usedSoFar}`)
|
|
|
+ if (oi.fullArray.length > usedSoFar) {
|
|
|
+ isNotEmpty = true
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if (isNotEmpty) {
|
|
|
await generate(true)
|
|
|
}
|
|
|
@@ -739,14 +1078,17 @@ const hiddenPage = async () => {
|
|
|
let row = parseInt(generateData.copyRange.topLeft.split(',')[1])
|
|
|
let colCount = parseInt(generateData.copyRange.topRight.split(',')[0]) - col
|
|
|
let rowCount = parseInt(generateData.copyRange.bottomLeft.split(',')[1]) - row
|
|
|
+
|
|
|
+ distributeArrayFieldToCells()
|
|
|
+
|
|
|
const sheet = previewSpread.getSheetFromName(generateData.sheetName)
|
|
|
if (!sheet) {
|
|
|
return;
|
|
|
}
|
|
|
if (generateData.hidden) {
|
|
|
- // 判断第一行,如果全部为空,则隐藏
|
|
|
let isEmpty = true;
|
|
|
- for (let i = 0; i < colCount; i++) {
|
|
|
+ for (let i = 0; i <= colCount; i++) {
|
|
|
+ if (i === 0) continue
|
|
|
const range = sheet.getCell(row, col + i)
|
|
|
if (range.value()) {
|
|
|
isEmpty = false;
|
|
|
@@ -757,17 +1099,36 @@ const hiddenPage = async () => {
|
|
|
sheet.visible(false)
|
|
|
}
|
|
|
}
|
|
|
- // 判断最后一行,如果不为空,自动续页
|
|
|
let isNotEmpty = false;
|
|
|
- for (let i = 0; i < colCount; i++) {
|
|
|
+ for (let i = 0; i <= colCount; i++) {
|
|
|
const range = sheet.getCell(row + rowCount, col + i)
|
|
|
if (range.value()) {
|
|
|
isNotEmpty = true;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ console.log('[hiddenPage] 单元格检测 isNotEmpty:', isNotEmpty, '| arrayFieldOffsetInfos:', arrayFieldOffsetInfos.length)
|
|
|
+
|
|
|
+ if (arrayFieldOffsetInfos.length > 0) {
|
|
|
+ for (const oi of arrayFieldOffsetInfos) {
|
|
|
+ const copyMinIndex = Math.min(...oi.fields.map(f => f.index))
|
|
|
+ const usedOnPage1 = (copyMinIndex - 1) + oi.rowsPerPage
|
|
|
+ console.log(`[hiddenPage] 前缀=${oi.prefix}, 数组长度=${oi.fullArray.length}, copyMinIndex=${copyMinIndex}, rowsPerPage=${oi.rowsPerPage}, usedOnPage1=${usedOnPage1}`)
|
|
|
+ if (oi.fullArray.length > usedOnPage1) {
|
|
|
+ isNotEmpty = true
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log('[hiddenPage] 最终 isNotEmpty:', isNotEmpty)
|
|
|
+
|
|
|
if (isNotEmpty) {
|
|
|
- handleGenerate(false)
|
|
|
+ await handleGenerate(false)
|
|
|
+ adjustBaseSheetArrays()
|
|
|
+ } else {
|
|
|
+ distributePageDataSources()
|
|
|
}
|
|
|
}
|
|
|
/**
|