Exemple #1
0
        static void Main(string[] args)
        {
            using (var presentationDocument =
                       DocumentFormat.OpenXml.Packaging.PresentationDocument.Open("测试.pptx", false))
            {
                var presentationPart = presentationDocument.PresentationPart;
                var presentation     = presentationPart.Presentation;

                // 先获取页面
                var slideIdList = presentation.SlideIdList;

                foreach (var slideId in slideIdList.ChildElements.OfType <SlideId>())
                {
                    // 获取页面内容
                    SlidePart slidePart = (SlidePart)presentationPart.GetPartById(slideId.RelationshipId);

                    var slide = slidePart.Slide;

                    foreach (var shape in
                             slide
                             .Descendants <DocumentFormat.OpenXml.Presentation.Shape>())
                    {
                        var defaultTextStyle = presentation.DefaultTextStyle;
                        var textBody         = shape.TextBody;

                        var textBodyListStyle = textBody.ListStyle;

                        Debug.Assert((textBodyListStyle?.ChildElements.Count ?? 0) == 0);

                        var paragraph = textBody.Descendants <Paragraph>().First();
                        var level     = paragraph.ParagraphProperties?.Level?.Value ?? 1;
                        Debug.Assert(level == 1);
                        Debug.Assert(paragraph.ParagraphProperties == null);

                        var paragraphProperties = defaultTextStyle.Level1ParagraphProperties;

                        foreach (var run in paragraph.Descendants <Run>())
                        {
                            var runProperties = run.RunProperties;
                            var eastAsianFont = runProperties.GetFirstChild <EastAsianFont>();
                            Debug.Assert(eastAsianFont == null);

                            eastAsianFont = paragraphProperties.GetFirstChild <DefaultRunProperties>()
                                            .GetFirstChild <EastAsianFont>();

                            var typeface = eastAsianFont.Typeface.Value;

                            Console.WriteLine($"字体是 {typeface}");

                            if (ThemeFontTypePattern.IsMatch(typeface))
                            {
                                // 进入这个分支,字体是 +mn-ea 字体
                                // 这个字体的意思里面 mn 表示 Body 字体
                                // 而 mj 表示 Title 字体,也就是 Major 字体
                                // 后续的 ea 和 lt 等表示采用东亚文字或拉丁文等
                                // 此时需要获取字体主题
                                var fontScheme = GetFontScheme(slidePart);
                                FontCollectionType fontCollection;

                                // mn 的 n 传入字符串是 +mn-ea 也就是第三个字符
                                if (typeface[2] == 'n')
                                {
                                    fontCollection = fontScheme.MinorFont;
                                }
                                else
                                {
                                    fontCollection = fontScheme.MajorFont;
                                }

                                FontLang fontLang = FontLang.Unknown;

                                if (typeface.Contains("lt"))
                                {
                                    fontLang = FontLang.LatinFont;
                                }
                                else if (typeface.Contains("cs"))
                                {
                                    fontLang = FontLang.ComplexScriptFont;
                                }
                                else if (typeface.Contains("ea"))
                                {
                                    fontLang = FontLang.EastAsianFont;
                                }

                                Debug.Assert(fontScheme != null);

                                var language = runProperties.Language;

                                Console.WriteLine("字体是" + GetFontFromFontCollection(GetScript(language), fontLang,
                                                                                    fontCollection));
                            }
                            else
                            {
                                // 这就是字体本身了
                                Console.WriteLine("字体是" + typeface);
                            }
                        }
                    }
                }
            }
        }
Exemple #2
0
        private static string GetFontFromFontCollection(string scriptTag, FontLang themeTypefaceFontLang,
                                                        FontCollectionType fontCollection)
        {
            if (fontCollection == null)
            {
                return(string.Empty);
            }

            // 假定存在对应的语言的字体,那么获取对应的字体
            // 存放方式如

            /*
             * <a:majorFont xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
             *  <a:latin typeface="Calibri Light" panose="020F0302020204030204" />
             *  <a:ea typeface="" />
             *  <a:cs typeface="" />
             *  <a:font script="Jpan" typeface="MS Pゴシック" />
             *  <a:font script="Hang" typeface="맑은 고딕" />
             *  <a:font script="Hans" typeface="宋体" />
             * </a:majorFont>
             * <a:minorFont xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
             *  <a:latin typeface="Calibri" panose="020F0502020204030204" />
             *  <a:ea typeface="" />
             *  <a:cs typeface="" />
             *  <a:font script="Jpan" typeface="MS Pゴシック" />
             *  <a:font script="Hang" typeface="맑은 고딕" />
             *  <a:font script="Hans" typeface="宋体" />
             * </a:minorFont>
             */

            foreach (var font in fontCollection.Elements <SupplementalFont>())
            {
                // <a:font script="Hang" typeface="맑은 고딕" />
                if (string.Equals(font.Script, scriptTag, StringComparison.OrdinalIgnoreCase))
                {
                    return(font.Typeface);
                }
            }

            // 也就是先尝试获取语言文化的,如果获取不到,就采用对应语言的
            TextFontType textFont = null;

            switch (themeTypefaceFontLang)
            {
            case FontLang.LatinFont:
                textFont = fontCollection.LatinFont;
                break;

            case FontLang.EastAsianFont:
                textFont = fontCollection.EastAsianFont;
                break;

            case FontLang.ComplexScriptFont:
                textFont = fontCollection.ComplexScriptFont;
                break;

            case FontLang.SymbolFont:
                // 特别不处理,为什么?
                // 在 fontCollection 是不存在的 SymbolFont 的
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(themeTypefaceFontLang), themeTypefaceFontLang, null);
            }

            var typeface = textFont?.Typeface?.Value;

            if (!string.IsNullOrEmpty(typeface))
            {
                return(typeface);
            }

            Debug.Assert(false, "找不到字体");

            return(null);
        }