コンピュータや音楽の事書いてます

Microsoft Office ファイルにアドイン用の設定情報を埋め込むまとめ

  • 埋め込む情報の親となるオブジェクトは
    • Powerpointの場合、Presentationと、Slide それぞれの配下にCustomerData がある
    • ExcelではWorkbookの配下にCustomXMLParts, Sheetの配下にCustomProperties がある
    • WordではThisDocumentの配下にCustomXMLPartsがある

ここではPowerpointを例に書きます。
Excel, Word なども似た様な要領で出来るはずです。

  • CustomerData の配下にはCustomXMLPartがあり、その配下にはCustomXMLNodeのツリーがある
    • 良くあるXML用のライブラリと似たような使用方法
    • using System.Xml.Serialization; を使えば、XML形式の設定情報 ↔ 設定情報Classを相互に変換できる


入れ物となるDocumentElementを作成 or 取得 (CustomXMLNode型)
製品名などを名前にしておけば、他のアドインとの競合などを防げる。

        CustomXMLNode ifNotExistsCreate(CustomerData cd)
        {
            var xps = cd.OfType<CustomXMLPart>().Where(x => x.DocumentElement.BaseName == "製品名など");
            if (!xps.Any())
            {
                var part = cd.Add();
                part.LoadXML("<製品名など></製品名など>");
                return part.DocumentElement;
            } else return xps.First().DocumentElement;

        }

設定情報をXMLに保存

        CustomXMLNode ifNotExistsCreate(CustomXMLNode node, string name)
        {
            var ret = node.SelectSingleNode(name);
            if (ret == null)
            {
                node.AppendChildNode(name);
                return node.SelectSingleNode(name);
            }
            else return ret;
        }

XML ー> Class 読み込み

        static public ChartSetting getChartSetting(Slide sld)
        {
            try
            {
                CustomerData cd = sld.CustomerData;
                var xps = cd.OfType<CustomXMLPart>().Where(x => x.DocumentElement.BaseName == "製品名など");
                if (!xps.Any()) return null;
                var sn = xps.First().SelectSingleNode("ChartSetting");
                if (sn == null) return null;
                var sb = new MemoryStream(Encoding.UTF8.GetBytes(sn.Text));
                var xml = XmlReader.Create(sb);

                var xs = new XmlSerializer(typeof(ChartSetting));
                return (ChartSetting)xs.Deserialize(xml);
            }catch(Exception e)
            {
                return null;
            }            
        }
    class ChartSetting {
        public int numOptions { get => _numOptions; set => _numOptions = value; }
        public float left { get => _left; set => _left = value; }
        public float top { get => _top; set => _top = value; }
        public float width { get => _width; set => _width = value; }
        public float height { get => _height; set => _height = value; }
        [XmlIgnore] //保存したくないものはこれをつける
        public Slide currentSlide { get => _currentSlide; set => _currentSlide = value; }