CoreXLSX icon indicating copy to clipboard operation
CoreXLSX copied to clipboard

Row.cells does not include empty cells.

Open matzsoft opened this issue 4 years ago • 14 comments

See the attached Package.swift, main.swift, and test.xlsx. The spreadsheet contains one worksheet with 3 rows and 3 columns. Yet when reading them Rows 1 and 3 show only 2 columns because ColumnB is empty. There should be 3 cells in each of the 3 rows.

If I am missing something in the documentation please let me know. Thanks.

Archive.zip

matzsoft avatar Apr 23 '20 01:04 matzsoft

Hey @matzsoft, in the XLSX format there's a difference between an empty cell and absence of a cell, like a difference between "" and nil. If you look at the internals of this file, it doesn't contain these cells. In general this is more efficient, especially for sparse spreadsheets. If you had a spreadsheet with a single cell Z1000000, it wouldn't contain millions of empty cells and a single cell with a value, it would only store a single cell, which is great as sparse spreadsheets can be quickly saved, loaded and also take less storage.

Please also see a similar conversation here.

Does that resolve your issue?

MaxDesiatov avatar Apr 23 '20 08:04 MaxDesiatov

Hey Max, you are of course correct about the structure of the XML and why they chose to implement it that way. And if your intent is to have CoreXLSX reflect the structure of the XML rather than the spreadsheet that it abstracts, then that is the way the library should behave.

However I am more interested in the table structure of the spreadsheet and need those missing cells to be there in the data I'm extracting. So here is a simple suggested patch that would make it easier for me to do that.

In ColumnReference.swift at line 13, make intValue public. Then in my

for c in wsRow.cells { I could more easily see which cells were not represented and treat them as empty.

Thanks.

matzsoft avatar Apr 23 '20 16:04 matzsoft

Sorry, after re-reading this I'm not sure I'm completely following how would you like it to work? Could you post a bigger code snippet of how you want the API to look like?

MaxDesiatov avatar Apr 23 '20 21:04 MaxDesiatov

Sure thing. Here's my file ExcelTable.swift after I made my suggested patch to ColumnReference.swift. After the patch I was able to create the extension for WorkSheet and add the two

row.append( contentsOf: Array( repeating: ...

and now it does what I need. Let me know if you have any other questions. Thanks. ExcelTable.swift.zip

matzsoft avatar Apr 23 '20 23:04 matzsoft

Hi

for (index, cell) in row.cells.enumerated() giving 6 cells in first row and 4 cells in second row as I have empty cells in second row. how can I get rows[1].cells.count = 6 (including empty rows).

jagan510710 avatar Mar 02 '21 08:03 jagan510710

i have this problem too :( make me headache

YangEhz avatar Mar 02 '21 10:03 YangEhz

i have this problem too :( make me headache

You found any solution?

jagan510710 avatar Mar 02 '21 11:03 jagan510710

I would like to reiterate that an empty cell and absence of a cell are different things. If you're not getting a cell or a row during the iteration, this means that there is no such cell or row in your document. The document should have empty cells and rows written in it in the first place for you to be able to read them.

MaxDesiatov avatar Mar 02 '21 13:03 MaxDesiatov

Because of absence of cell we have index problem. in first row I have email at index 3. in second row I have email at index 2.

jagan510710 avatar Mar 02 '21 14:03 jagan510710

You should not address cells via their indices in an array of cells. Every cell has a reference property, which you can read to understand where exactly a given cell is located. Corresponding properties on the CellReference struct give you the exact position of a cell.

MaxDesiatov avatar Mar 02 '21 14:03 MaxDesiatov

You should not address cells via their indices in an array of cells. Every cell has a reference property, which you can read to understand where exactly a given cell is located. Corresponding properties on the CellReference struct give you the exact position of a cell.

Thanks @MaxDesiatov it is working now...

jagan510710 avatar Mar 02 '21 14:03 jagan510710

Sorry, I haven't figured it out yet, can I have a code reference?

YangEhz avatar Mar 03 '21 02:03 YangEhz

My method is like this `func stringValue(_ sharedStrings: SharedStrings) -> String? { guard type == .sharedString, let index = value.flatMap(Int.init) else {

        if value == nil {
            return ""
        }
        return value
        
    }
    
    return sharedStrings.items[index].text
}`

In CellQueries.swift -> public extension Cell, i added a line of code,But I don’t know if it will cause any bugs P.S. apologize for my poor English...

YangEhz avatar Mar 03 '21 08:03 YangEhz

You should not address cells via their indices in an array of cells. Every cell has a reference property, which you can read to understand where exactly a given cell is located. Corresponding properties on the CellReference struct give you the exact position of a cell.

Thanks @MaxDesiatov it is working now...

Hi, may I ask how did you solve the problem?

Ververtom avatar Dec 08 '23 03:12 Ververtom