【问题标题】:Extract table from NSAttributedString从 NSAttributedString 中提取表
【发布时间】:2018-10-30 04:38:50
【问题描述】:

假设我从文件 (html 或 rtf) 中读取了NSAttributedString,并且在该文件中我清楚地看到了几个表格。有没有办法提取这些表或至少找到与该表对应的NSRange?如果我能以某种方式从NSAttributedString 提取(数组)NSTextTableBlock、NSTextTable 或NSTextBlock,那将是理想的。但如果这不可能,那么至少应该有一种方法可以找到表格单元格的 NSRange 或类似的东西。 Swift(可能是 4 个)是首选,但 obj-c 也可以。

例如想象这样的场景:

let html =
"""
<table style="height: 51px;" width="147">
    <tbody>
        <tr>
            <td style="width: 65.5px;">a</td>
            <td style="width: 65.5px;">b</td>
        </tr>
        <tr>
            <td style="width: 65.5px;">c</td>
            <td style="width: 65.5px;">d</td>
        </tr>
    </tbody>
</table>
"""
var str = NSAttributedString(html: html.data(using: .utf8)!,    options: [:], documentAttributes: nil)!

然后我想或多或少地做一些这样的事情:

for table in str{
    for row in table{
        for cell in row{
            //do something
        }
    }
}

【问题讨论】:

  • 你能发布你需要的例子吗

标签: swift nsattributedstring rtf nsrange


【解决方案1】:

我为这个问题找到了一个有点幼稚的解决方案,但它确实有效。您基本上遍历 NSAttributedString 中的所有字符,查询它们的属性,然后检查其中是否是带有表格的 NSParagraphStyle。

这段代码从给定位置提取 NSTextTable 数组(记住表格可以嵌套)

extension NSAttributedString{

func paragraphStyle(at index:Int)->NSParagraphStyle?{
    let key = NSAttributedStringKey.paragraphStyle
    return attribute(key, at: index, effectiveRange: nil) as! NSParagraphStyle?
}
func textBlocks(at index:Int)->[NSTextBlock]?{
    return paragraphStyle(at: index)?.textBlocks
}
func tables(at index:Int)->[NSTextTable]?{
    guard let tbs = textBlocks(at: index) else{
        return nil
    }
    var output = Set<NSTextTable>()
    for tb in tbs{
        if let t = tb as? NSTextTableBlock{
            output.insert(t.table)
        }
    }
    return Array(output)
}

}

这可以帮助您收集所有表格(嵌套表格除外 - 为了也收集它们,您必须在每个表格中递归地运行此函数):

extension NSAttributedString{

var outterTables:[NSTextTable]{
    var index = 0
    let len = length
    var output:[NSTextTable] = []
    while index < len{
        if let tab = outterTable(at: index){
            output.append(tab)
            index = range(of: tab, at: index).upperBound
        }else{
            index += 1
        }
    }
    return output
}

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多