Excel2007のファイル形式
xlsxってzipファイルだったんですね。全然チェック入れてませんでした。OpenXML SDKで操作できるようなのでSDKをダウンロードしてみたけど、使い方がさっぱりです。他にも、Code Snippetによるサンプルとかも見ましたけど、ちょっとした作業をするにも、もの凄いコード量です。
セルから値を取得するだけで、これはありえないでしょう・・・
public static string XLGetCellValue(string fileName, string sheetName, string addressName) { // Return the value of the specified cell. const string documentRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"; const string worksheetSchema = "http://schemas.openxmlformats.org/spreadsheetml/2006/main"; const string sharedStringsRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings"; const string sharedStringSchema = "http://schemas.openxmlformats.org/spreadsheetml/2006/main"; string cellValue = null; // Retrieve the stream containing the requested // worksheet's info: using (Package xlPackage = Package.Open(fileName, FileMode.Open, FileAccess.Read)) { PackagePart documentPart = null; Uri documentUri = null; // Get the main document part (workbook.xml). foreach (System.IO.Packaging.PackageRelationship relationship in xlPackage.GetRelationshipsByType(documentRelationshipType)) { // There should only be one document part in the package. documentUri = PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative), relationship.TargetUri); documentPart = xlPackage.GetPart(documentUri); // There should only be one instance, but get out no matter what. break; } if (documentPart != null) { // Load the contents of the workbook. XmlDocument doc = new XmlDocument(); doc.Load(documentPart.GetStream()); // Create a namespace manager, so you can search. // Add a prefix (d) for the default namespace. NameTable nt = new NameTable(); XmlNamespaceManager nsManager = new XmlNamespaceManager(nt); nsManager.AddNamespace("d", worksheetSchema); nsManager.AddNamespace("s", sharedStringSchema); string searchString = string.Format("//d:sheet[@name='{0}']", sheetName); XmlNode sheetNode = doc.SelectSingleNode(searchString, nsManager); if (sheetNode != null) { // Get the relId attribute: XmlAttribute relationAttribute = sheetNode.Attributes["r:id"]; if (relationAttribute != null) { string relId = relationAttribute.Value; // First, get the relation between the document and the sheet. PackageRelationship sheetRelation = documentPart.GetRelationship(relId); Uri sheetUri = PackUriHelper.ResolvePartUri(documentUri, sheetRelation.TargetUri); PackagePart sheetPart = xlPackage.GetPart(sheetUri); // Load the contents of the workbook. XmlDocument sheetDoc = new XmlDocument(nt); sheetDoc.Load(sheetPart.GetStream()); XmlNode cellNode = sheetDoc.SelectSingleNode(string.Format("//d:sheetData/d:row/d:c[@r='{0}']", addressName), nsManager); if (cellNode != null) { // Retrieve the value. The value may be stored within // this element. If the "t" attribute contains "s", then // the cell contains a shared string, and you must look // up the value individually. XmlAttribute typeAttr = cellNode.Attributes["t"]; string cellType = string.Empty; if (typeAttr != null) { cellType = typeAttr.Value; } XmlNode valueNode = cellNode.SelectSingleNode("d:v", nsManager); if (valueNode != null) { cellValue = valueNode.InnerText; } // Check the cell type. At this point, this code only checks // for booleans and strings individually. if (cellType == "b") { if (cellValue == "1") { cellValue = "TRUE"; } else { cellValue = "FALSE"; } } else if (cellType == "s") { // Go retrieve the actual string from the associated string file. foreach (System.IO.Packaging.PackageRelationship stringRelationship in documentPart.GetRelationshipsByType(sharedStringsRelationshipType)) { // There should only be one shared string reference, so you'll exit this loop immediately. Uri sharedStringsUri = PackUriHelper.ResolvePartUri(documentUri, stringRelationship.TargetUri); PackagePart stringPart = xlPackage.GetPart(sharedStringsUri); if (stringPart != null) { // Load the contents of the shared strings. XmlDocument stringDoc = new XmlDocument(nt); stringDoc.Load(stringPart.GetStream()); // Add the string schema to the namespace manager: nsManager.AddNamespace("s", sharedStringSchema); int requestedString = Convert.ToInt32(cellValue); string strSearch = string.Format("//s:sst/s:si[{0}]", requestedString + 1); XmlNode stringNode = stringDoc.SelectSingleNode(strSearch, nsManager); if (stringNode != null) { cellValue = stringNode.InnerText; } } } } } } } } } return cellValue; }
セルから値を取得と言ったら、
SpreadSheetDocument.WorkbookPart.WorksheetParts[0].Cells[0,0].Value;
これくらいの手軽さであるべきじゃないかしら。(^^;