Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Enhancement] Access worksheet by name #75

Open
GoldenJoe opened this issue Jun 30, 2019 · 1 comment
Open

[Enhancement] Access worksheet by name #75

GoldenJoe opened this issue Jun 30, 2019 · 1 comment
Assignees
Labels
enhancement New feature or request

Comments

@GoldenJoe
Copy link

It would be convenient if there was something like file.parseWorksheet(filepath: "xmlfile.xml", name: "myworksheet")

@MaxDesiatov MaxDesiatov self-assigned this Jun 30, 2019
@GoldenJoe
Copy link
Author

GoldenJoe commented Jul 2, 2019

I came up with a little convenience function for this earlier today. Wasn't sure if you would rather have this functionality in CoreXLSX.swift or as an extension of Worksheet, so I figure I'd just post it here and let you decide where to put it.

func getWorksheet(file: XLSXFile, name: String) throws -> Worksheet?
{
    // Get the ID of the sheet we want
    // NOTE:A workbook should not be able to have two worksheets with the same name...should we assume this is always true, though?
    //      If not, then we can use the commented code below.
    let sheets = try file.parseWorkbooks()
        .flatMap { $0.sheets.items }
        .filter { $0.name == name }
    if(sheets.isEmpty){ // no sheet with name
        return nil
    }
    // Throw Error? - multiple sheets with same name (should not be possible)
    // if(sheets.count > 1){}
    
    let rID = sheets[0].relationship
    //let rID = sheets.map { $0.relationship } // if multiple sheets with the same name is possible, use this to get an array of relationship IDs
    
    // Explanation:
    // parseDocumentPaths will give us something like: ["xl/workbook.xml"]
    // get the relationships for that workbook (Path, [Relationship])
    //      CoreXLSX.Relationship(id: "rId3", type: CoreXLSX.Relationship.SchemaType.worksheet, target: "worksheets/sheet3.xml"),
    //      CoreXLSX.Relationship(id: "rId2", type: CoreXLSX.Relationship.SchemaType.worksheet, target: "worksheets/sheet2.xml"),
    //      CoreXLSX.Relationship(id: "rId1", type: CoreXLSX.Relationship.SchemaType.worksheet, target: "worksheets/sheet1.xml"),
    // filter out the relationships with the IDs we want, and flatMap the paths
    let paths = try file.parseDocumentPaths().map {
        // For each document path, gets its relationships
        try file.parseDocumentRelationships(path: $0) // returns (Path, [Relationship])
        }.flatMap { (path, relationships) -> [String] in
            let worksheets = relationships.items.filter { $0.id == rID }
            //let worksheets = relationships.items.filter { rIDArr.contains($0.id) } // if multiple sheets with the same name is possible
            guard !path.isRoot else { return worksheets.map { $0.target } }
            
            // .rels file has paths relative to its directory,
            // storing that path in `pathPrefix`
            let pathPrefix = path.components.dropLast().joined(separator: "/")
            
            return worksheets.map { "\(pathPrefix)/\($0.target)" }
    }
    
    if(paths.isEmpty){ // no paths for the worksheets
        return nil
    }
    // Throw Error? - multiple paths for the worksheet name (should not be possible)
    // if(paths > 1){}
    
    return try file.parseWorksheet(at: paths[0])
}

@MaxDesiatov MaxDesiatov changed the title [Enhancement] Access worksheet by name. [Enhancement] Access worksheet by name Apr 6, 2020
@MaxDesiatov MaxDesiatov added the enhancement New feature or request label Apr 6, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants