mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-11-10 21:32:43 +08:00
fix(parser): grow truncated rows to host inherited merge values (#21044)
This commit is contained in:
1 parent
150977db52
commit
a2f22bebb5
2 files changed
+44
-7
No files matched your search
@@ -594,11 +594,14 @@ func inheritMergedHeader(records [][]string, headerRowIdx int, mm map[[2]int][2]
|
||||
|
||||
// inheritMergedDataCells fills empty cells of non-header rows with the value
|
||||
// of their merge master, so a vertically merged group label (e.g. A2:A4) is
|
||||
// visible on every data row instead of only the first. Unlike the header-row
|
||||
// path above, data rows are never widened: only cells already present in the
|
||||
// row slice are filled, so a far merge cannot allocate a sea of empty <td>
|
||||
// cells (see padRowToWidth for the blow-up this avoids). Call with absolute
|
||||
// sheet row numbers, before records are reordered around the header row.
|
||||
// visible on every data row instead of only the first. excelize truncates
|
||||
// each row at its last valued cell, so a slave cell past that point is absent
|
||||
// from the slice: the row is then extended exactly up to the slave column to
|
||||
// host the real inherited value. The extension is bounded by the master row's
|
||||
// own width (the master cell must exist and be non-empty), so unlike header
|
||||
// padding it cannot chase a far merge across the sheet (see padRowToWidth).
|
||||
// Call with absolute sheet row numbers, before records are reordered around
|
||||
// the header row.
|
||||
func inheritMergedDataCells(rows [][]string, headerRow int, ranges []mergeRange) {
|
||||
for _, r := range ranges {
|
||||
// Vertical merges only: a horizontally merged data cell is already
|
||||
@@ -629,8 +632,10 @@ func inheritMergedDataCells(rows [][]string, headerRow int, ranges []mergeRange)
|
||||
if row == headerRow {
|
||||
continue
|
||||
}
|
||||
if r.sc > len(rows[row-1]) {
|
||||
continue
|
||||
// Grow a truncated row exactly up to the slave column; the
|
||||
// appended cells stay empty except the inherited value below.
|
||||
for len(rows[row-1]) < r.sc {
|
||||
rows[row-1] = append(rows[row-1], "")
|
||||
}
|
||||
if strings.TrimSpace(rows[row-1][r.sc-1]) == "" {
|
||||
rows[row-1][r.sc-1] = master
|
||||
|
||||
@@ -566,6 +566,38 @@ func TestXLSXParser_MergedDataCellHorizontalUntouched(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestXLSXParser_MergedDataCellBeyondTruncation asserts a merged slave cell
|
||||
// past its row's truncation point (excelize drops trailing empties) is still
|
||||
// filled: the row grows exactly up to the slave column to host the value.
|
||||
func TestXLSXParser_MergedDataCellBeyondTruncation(t *testing.T) {
|
||||
data := newTestXLSX(t, func(f *excelize.File) {
|
||||
mustSetCell(t, f, "Sheet1", "A1", "name")
|
||||
mustSetCell(t, f, "Sheet1", "B1", "age")
|
||||
mustSetCell(t, f, "Sheet1", "C1", "department")
|
||||
mustSetCell(t, f, "Sheet1", "D1", "notes")
|
||||
mustSetCell(t, f, "Sheet1", "A2", "Mike")
|
||||
mustSetCell(t, f, "Sheet1", "B2", 28)
|
||||
mustSetCell(t, f, "Sheet1", "C2", "Sales")
|
||||
mustSetCell(t, f, "Sheet1", "D2", "Important customer")
|
||||
mustMergeCell(t, f, "Sheet1", "A2", "A3")
|
||||
mustMergeCell(t, f, "Sheet1", "B2", "B3")
|
||||
mustMergeCell(t, f, "Sheet1", "D2", "D3")
|
||||
// Row 3's own value sits before the merged columns, so GetRows
|
||||
// truncates the row short of the D3 slave.
|
||||
mustSetCell(t, f, "Sheet1", "C3", "IT")
|
||||
})
|
||||
p, _ := NewXLSXParser("")
|
||||
res := p.ParseWithResult(t.Context(), "t.xlsx", data)
|
||||
if res.Err != nil {
|
||||
t.Fatalf("ParseWithResult: %v", res.Err)
|
||||
}
|
||||
text := spreadsheetText(res)
|
||||
want := "<tr><td>Mike</td><td>28</td><td>IT</td><td>Important customer</td></tr>"
|
||||
if !strings.Contains(text, want) {
|
||||
t.Fatalf("truncated slave cells not filled, got:\n%s", text)
|
||||
}
|
||||
}
|
||||
|
||||
// TestXLSXParser_MergedHeaderDownIntoDataUntouched asserts a vertical merge
|
||||
// mastered on the header row does not leak the header label into data rows.
|
||||
func TestXLSXParser_MergedHeaderDownIntoDataUntouched(t *testing.T) {
|
||||
|
||||
Reference in new issue
Block a user