我想导出包含数据的Excel文件,以便我的用户可以:
基本上我会给他们一个离线文件的经验,如果他们没有任何互联网访问权限,他们就可以编辑(因为我们是一个Web应用程序)
使用OpenXml SDK创建Excel文件时,我使用OpenXmlElement.SetAttribute方法将属性添加到工作表的列,行和单元格中。使用我添加的属性,以便在重新导入时,我可以将编辑的数据与应该存储的位置进行匹配。
我导出的属性是:
对于单元格,导出例程如下所示:
var cell = new Cell {
CellReference = string.Format("{0}{1}", Column.Reference, Row.Index),
DataType = this.CellDataType
};
foreach (var keyValuePair in this.AttributeDictionary) {
cell.SetAttribute(new OpenXmlAttribute {
LocalName = keyValuePair.Key,
Value = keyValuePair.Value.ToString()
});
}
此导出正常。在OpenXml Productivity Tool中检查导出的文件时,我可以看到属性已正确添加。在Excel中编辑后保存文件时,不会保留属性。有没有办法告诉Excel保留属性,还是有另一种方法可以最好地保存我需要的数据,以便轻松重新输入数据?
旁边问题:
如果Excel不保留它们,有哪些属性?
答案 0 :(得分:1)
我认为您不能强制Excel绕过未知的属性,但您可以使用ExtensionLists
和Extensions
添加扩展元素。 Excel将往返这些元素,并设计(据我所知)存储应用程序特定数据,就像您一样。
似乎没有太多关于我可以找到的文档,但是ECMA-376 spec的第3部分提到了扩展。
以下代码将创建一个工作表,其中包含单元格A1中的值和ExtensionList
,其中包含一个Extension
作为该单元格的子级:
public static void CreateSpreadsheetWorkbook(string filepath)
{
if (File.Exists(filepath))
File.Delete(filepath);
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(filepath, SpreadsheetDocumentType.Workbook))
{
// Add a WorkbookPart to the document.
WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
// Add a WorksheetPart to the WorkbookPart.
WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
SheetData sheetData = new SheetData();
worksheetPart.Worksheet = new Worksheet(sheetData);
// Add Sheets to the Workbook.
Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
// Append a new worksheet and associate it with the workbook.
Sheet sheet = new Sheet()
{
Id = spreadsheetDocument.WorkbookPart.
GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "Sheet1"
};
sheets.Append(sheet);
Row row = new Row()
{
RowIndex = 1U
};
Cell cell = new Cell()
{
CellReference = "A1",
CellValue = new CellValue("A Test"),
DataType = CellValues.String
};
ExtensionList extensions = new ExtensionList();
Extension extension = new Extension()
{
Uri = "Testing1234"
};
extensions.AppendChild(extension);
extension.AddNamespaceDeclaration("ns", "http://tempuri/someUrl");
cell.AppendChild(extensions);
row.Append(cell);
sheetData.Append(row);
workbookpart.Workbook.Save();
// Close the document.
spreadsheetDocument.Close();
}
}
以下内容将再次读取该值,即使该文件已经通过Excel进行了四舍五入。
public static void ReadSheet(string filename, string sheetName)
{
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(filename, false))
{
WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart;
//get the correct sheet
Sheet sheet = workbookPart.Workbook.Descendants<Sheet>().Where(s => s.Name == sheetName).First();
if (sheet != null)
{
WorksheetPart worksheetPart = workbookPart.GetPartById(sheet.Id) as WorksheetPart;
foreach (Cell cell in worksheetPart.Worksheet.Descendants<Cell>())
{
ExtensionList extensions = cell.GetFirstChild<ExtensionList>();
if (extensions != null)
{
Extension extension = extensions.GetFirstChild<Extension>();
if (extension != null)
{
Console.WriteLine("Cell {0} has value {1}", cell.CellReference, extension.Uri);
}
}
}
}
}
}
输出
单元格A1的值为Testing1234
关于你的问题:
如果Excel不保留它们,有哪些属性?
我不太确定 - 我使用OpenXmlAttribute
类的唯一一次是当我使用SAX方法编写文档时。在这种情况下,您需要明确地将属性与元素一起编写。例如:
List<OpenXmlAttribute> oxa = new List<OpenXmlAttribute>();
//cell reference attribute
oxa.Add(new OpenXmlAttribute("r", "", "A1"));
//cell type attribute
oxa.Add(new OpenXmlAttribute("t", "", "str"));
//write the start element of a cell with the above attributes
oxw.WriteStartElement(new Cell(), oxa);
//write a value to the cell
oxw.WriteElement(new CellValue("Test"));
//write the end element
oxw.WriteEndElement();
我的answer here有一个使用SAX方法的完整示例。