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;

これくらいの手軽さであるべきじゃないかしら。(^^;