                     let data = "<Data ss:Type=\"\(cell.type.rawValue)\">\(cell.value)</Data>"
                     
                     //style
+                    let styleId: String
                     let styleValue = TextAttribute.styleValue(for: cell.attributes)
-                    let styleId = appendStyle(styleValue)
+                    if let id = styles.filter({ k, v in v == styleValue }).first?.key {
+                        styleId = id //reuse existing style
+                    } else {
+                        styleId = appendStyle(styleValue) //create new style
+                    }
                     
                     let merge = cell.colspan.map{ "ss:MergeAcross=\"\($0)\"" } ?? ""
                     

            case .color(let c): return "ss:Color=\"\(c.hexString())\""
            }
        }
    }
    
    case backgroundColor(Color)

        }
    }
    
    public static func a(lhs: TextAttribute, rhs: TextAttribute) -> Bool {
        switch (lhs, rhs) {
        case (.backgroundColor(let l), .backgroundColor(let r)): return l == r
        case (.font(let l), .font(let r)): return l == r
        case (.format(let l), .format(let r)): return l == r
        default: return false
        }
    }
    
//    static func compare(_ attributes: [TextAttribute], with: [TextAttribute]) -> Bool {
//        
//    }
    
    static func styleValue(for textAttributes: [TextAttribute]) -> String {
        guard textAttributes.count > 0 else { return "" }
        
