public static Dictionary<string, Dictionary<string, string>> Read([NotNull] string filename, [NotNull] string localeId) {
var r = new Dictionary<string, Dictionary<string, string>>();
using (var zip = ZipArchive.Open(filename)) {
var n = XNamespace.Get("http://schemas.openxmlformats.org/spreadsheetml/2006/main");
var s = XDocument.Parse(zip.Entries.First(x => x.Key == "xl/sharedStrings.xml")
.OpenEntryStream().ReadAsStringAndDispose())
.Descendants(n + "si").Select(x => x.Element(n + "t")?.Value ?? "<NULL>").ToList();
var i = XDocument.Parse(zip.Entries.First(x => x.Key == "xl/workbook.xml")
.OpenEntryStream().ReadAsStringAndDispose())
.Descendants(n + "sheet")
.FirstOrDefault(x => x.Attribute("name")?.Value.IndexOf($"({localeId})", StringComparison.OrdinalIgnoreCase) != -1)?
.Attribute("sheetId")?.Value;
if (i == null) return r;
var c = XDocument.Parse(zip.Entries.First(x => x.Key == $"xl/worksheets/sheet{i.ToInvariantString()}.xml")
.OpenEntryStream().ReadAsStringAndDispose())
.Descendants(n + "c").Select(x => new Cell(x)).ToList();
foreach (var x in c.Where(x => x.Location?.StartsWith("B") == true && x.Location != "B1")) {
var g = c.GetString(x.Location.Replace("B", "A"), s);
var t = c.GetString(x.Location.Replace("B", "D"), s);
var k = s.ElementAtOrDefault(x.Node.Element(n + "v")?.Value.AsInt() ?? -1);
if (k == null || t == null || g == null) continue;
Dictionary<string, string> gd;
if (r.TryGetValue(g, out gd)) {
gd.Add(k, t);
} else {
gd = new Dictionary<string, string>(200) { { k, t } };
r[g] = gd;
}
}
return r;
}
}
}