Skip to content

Support For Writing Rich Strings #8

@bdkjones

Description

@bdkjones

I've added support for writing rich strings to the wrapper, but my custom fork has very extensive changes in style and formatting, so a direct PR isn't possible. I'm putting my code here so that you can adapt it to your style and add it to the wrapper.

Fragment Struct

This simple object holds information about one fragment of a rich string. In your module, ExcelFormat is named just Format, I think:

///
///  Represents one fragment of a rich string: a substring and, optionally, a format to apply to that substring.
///
///  Warning: Libxlsxwriter will throw an error if two consecutive fragments of a rich string have the same format object.
///
struct ExcelRichStringFragment
{
    var format: ExcelFormat?
    var string: String
    
    init(_ string: String, format: ExcelFormat? = nil)
    {
        self.string = string
        self.format = format
    }
}

Worksheet Addition

This method accepts an array of ExcelRichStringFragment and writes the rich string to a particular cell:

    ///
    ///  Writes a rich string to a given cell by assembling the rich string fragments. The final format parameter should contain
    ///  attributes that apply to the cell, but not the string (border type/color, background color, etc.) Including such attributes 
    ///  in the formats applied to each string fragment will fail to apply them to the cell.
    ///
    ///  WARNING: It is an error for two consecutive fragments to share the same format object, or for a fragment to have an empty string.
    ///
    @discardableResult func writeRichString(fragments: [ExcelRichStringFragment], at cell: ExcelCell, format: ExcelFormat? = nil) throws -> ExcelWorksheet
    {
        guard !fragments.isEmpty else {
            return self
        }

        let mainFormat = format?.lxw_format
        
        var rawTuples: [lxw_rich_string_tuple] = []
        for fragment: ExcelRichStringFragment in fragments
        {
            let f = fragment.format?.lxw_format
            let s = UnsafeMutablePointer<Int8>(mutating: (fragment.string as NSString).utf8String)
            
            let t = lxw_rich_string_tuple(format: f, string: s)
            rawTuples.append(t)
        }
        
        rawTuples.withUnsafeMutableBufferPointer { p in
            
            guard let arrBaseAddress = p.baseAddress else { return }

            var pointersToEachArrayElement: [UnsafeMutablePointer<lxw_rich_string_tuple>?] = Array(arrBaseAddress ..< arrBaseAddress.advanced(by: p.count))
            pointersToEachArrayElement.append(nil)
            
            _ = pointersToEachArrayElement.withUnsafeMutableBufferPointer { q in
                worksheet_write_rich_string(lxw_worksheet, cell.row, cell.col, q.baseAddress, mainFormat)
            }
        }
        
        return self
    }

Example Usage

let f1: ExcelFormat = book.addFormat()
f1.fontColor(.red)
        
let f2: ExcelFormat = book.addFormat()
f2.fontColor(.blue)

let frag1 = ExcelRichStringFragment("This is", format: f1)
let frag2 = ExcelRichStringFragment(" a test.", format: f2)
        
try sheet.writeRichString(fragments: [frag1, frag2], at: "D10")

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions