Как сохранить.NET DateTime в OpenDocument
Я использую C#, чтобы написать электронную таблицу OpenDocument в XML. Нет проблем с записью двойных значений, которые отлично работают так:
private void SaveFloatCell(XmlNode rowNode, XmlDocument ownerDocument, double number)
{
XmlElement cellNode = ownerDocument.CreateElement("table:table-cell", this.GetNamespaceUri("table"));
XmlAttribute valueType = ownerDocument.CreateAttribute("office:value-type", this.GetNamespaceUri("office"));
valueType.Value = "float";
cellNode.Attributes.Append(valueType);
XmlAttribute value = ownerDocument.CreateAttribute("office:value", this.GetNamespaceUri("office"));
value.Value = number.ToString(CultureInfo.InvariantCulture);
cellNode.Attributes.Append(value);
rowNode.AppendChild(cellNode);
}
Однако при попытке сохранить значения DateTime я не могу заставить их отображаться правильно. Это то, что я до сих пор, который отображает "2012" в ячейке вместо указанного формата даты:
private void SaveDateTimeCell(XmlNode rowNode, XmlDocument ownerDocument, double number, string format)
{
XmlElement cellNode = ownerDocument.CreateElement("table:table-cell", this.GetNamespaceUri("table"));
XmlAttribute valueType = ownerDocument.CreateAttribute("office:value-type", this.GetNamespaceUri("office"));
valueType.Value = "date";
cellNode.Attributes.Append(valueType);
XmlAttribute value = ownerDocument.CreateAttribute("office:value", this.GetNamespaceUri("office"));
value.Value = Utils.DateTime(number).ToString("yyyy-mm-ddThh:mm:ss");
cellNode.Attributes.Append(value);
rowNode.AppendChild(cellNode);
}
Я потратил довольно много времени, играя с различными фрагментами кода, которые нашел, но безуспешно. В любом случае, есть ли какая-нибудь щедрая душа, которая может помочь мне с этим?
Большое спасибо!
2 ответа
Хорошо, у меня есть ответ. Окончательный код выглядит так:
private void SaveDateTimeCell(XmlNode rowNode, XmlDocument ownerDocument, double number, string format)
{
XmlElement cellNode = ownerDocument.CreateElement("table:table-cell", this.GetNamespaceUri("table"));
XmlAttribute valueType = ownerDocument.CreateAttribute("office:value-type", this.GetNamespaceUri("office"));
valueType.Value = "date";
cellNode.Attributes.Append(valueType);
XmlAttribute value = ownerDocument.CreateAttribute("office:date-value", this.GetNamespaceUri("office"));
value.Value = Utils.DateTime(number).ToString("yyyy-MM-ddTHH:mm:ss");
cellNode.Attributes.Append(value);
XmlAttribute tableStyleName = ownerDocument.CreateAttribute("table:style-name", this.GetNamespaceUri("table"));
tableStyleName.Value = "ce2";
cellNode.Attributes.Append(tableStyleName);
rowNode.AppendChild(cellNode);
}
Это определение "ce2", которое является ключевым. Это делается в файле styles.xml распакованного файла *.ods:
private void SaveStyleSheet(XmlNode sheetsRootNode)
{
XmlDocument ownerDocument = sheetsRootNode.OwnerDocument;
XmlNode sheetNode = ownerDocument.CreateElement("number:date-style", this.GetNamespaceUri("number"));
XmlAttribute styleName = ownerDocument.CreateAttribute("style:name", this.GetNamespaceUri("style"));
styleName.Value = "N19";
sheetNode.Attributes.Append(styleName);
XmlElement numberDay = ownerDocument.CreateElement("number:day", this.GetNamespaceUri("number"));
XmlAttribute numberStyle = ownerDocument.CreateAttribute("number:style", this.GetNamespaceUri("number"));
numberStyle.Value = "long";
numberDay.Attributes.Append(numberStyle);
sheetNode.AppendChild(numberDay);
XmlElement numberText = ownerDocument.CreateElement("number:text", this.GetNamespaceUri("number"));
numberText.InnerText = "/";
sheetNode.AppendChild(numberText);
XmlElement numberMonth = ownerDocument.CreateElement("number:month", this.GetNamespaceUri("number"));
XmlAttribute numberStyle2 = ownerDocument.CreateAttribute("number:style", this.GetNamespaceUri("number"));
numberStyle2.Value = "long";
numberMonth.Attributes.Append(numberStyle2);
sheetNode.AppendChild(numberMonth);
XmlElement numberText2 = ownerDocument.CreateElement("number:text", this.GetNamespaceUri("number"));
numberText2.InnerText = "/";
sheetNode.AppendChild(numberText2);
XmlElement numberYear = ownerDocument.CreateElement("number:year", this.GetNamespaceUri("number"));
XmlAttribute numberStyle3 = ownerDocument.CreateAttribute("number:style", this.GetNamespaceUri("number"));
numberStyle3.Value = "long";
numberYear.Attributes.Append(numberStyle3);
sheetNode.AppendChild(numberYear);
sheetsRootNode.AppendChild(sheetNode);
}
Этот стиль даты N19 затем упоминается в автоматических стилях файла content.xml распакованного файла *.ods, таким образом:
private void SaveAutomaticStyleSheet(XmlNode sheetsRootNode)
{
XmlDocument ownerDocument = sheetsRootNode.OwnerDocument;
XmlNode sheetNode = ownerDocument.CreateElement("style:style", this.GetNamespaceUri("style"));
XmlAttribute styleName = ownerDocument.CreateAttribute("style:name", this.GetNamespaceUri("style"));
styleName.Value = "ce2";
sheetNode.Attributes.Append(styleName);
XmlAttribute styleFamily = ownerDocument.CreateAttribute("style:family", this.GetNamespaceUri("style"));
styleFamily.Value = "table-cell";
sheetNode.Attributes.Append(styleFamily);
XmlAttribute styleParentStyleName = ownerDocument.CreateAttribute("style:parent-style-name", this.GetNamespaceUri("style"));
styleParentStyleName.Value = "Default";
sheetNode.Attributes.Append(styleParentStyleName);
XmlAttribute styleDataStyleName = ownerDocument.CreateAttribute("style:data-style-name", this.GetNamespaceUri("style"));
styleDataStyleName.Value = "N19";
sheetNode.Attributes.Append(styleDataStyleName);
sheetsRootNode.AppendChild(sheetNode);
}
На самом деле, предложения Джона были необходимы и для того, чтобы код работал идеально. Так что еще раз спасибо Джон. Во всяком случае, черный, черный искусство действительно...:)
Возможно, вам просто нужно исправить свой формат, учитывая, что он в настоящее время не работает:
value.Value = Utils.DateTime(number).ToString("yyyy-MM-ddTHH:mm:ss");
Изменения:
- Используйте M для месяца, а не m (что означает минуты)
- Используйте HH для часов, а не для чч (12 часов)
Я бы предложил уточнить CultureInfo.InvariantCulture
также, чтобы показать, что вы не хотите применять какие-либо культурные настройки.