Пример #1
0
        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            var file = new FileInfo("Test.pptx");

            var tf = @"F:\temp\KewalnaidiNaborereefal.pptx";

            if (File.Exists(tf))
            {
                file = new FileInfo(tf);
            }

            long lastAllocatedBytesForCurrentThread;

            using var presentationDocument = PresentationDocument.Open(file.FullName, false);
            var slide = presentationDocument.PresentationPart !.SlideParts.First().Slide;

            var graphicFrame     = slide.CommonSlideData !.ShapeTree !.GetFirstChild <GraphicFrame>() !;
            var graphic          = graphicFrame.Graphic !;
            var graphicData      = graphic.GraphicData !;
            var alternateContent = graphicData.GetFirstChild <AlternateContent>() !;
            var choice           = alternateContent.GetFirstChild <AlternateContentChoice>() !;
            var oleObject        = choice.GetFirstChild <OleObject>() !;

            Debug.Assert(oleObject.GetFirstChild <OleObjectEmbed>() != null);
            var id   = oleObject.Id !;
            var part = slide.SlidePart !.GetPartById(id !);

            Debug.Assert(part.ContentType == "application/vnd.openxmlformats-officedocument.oleObject");

            var allocatedBytesForCurrentThread = GC.GetAllocatedBytesForCurrentThread();
            var s = part.GetStream();

            lastAllocatedBytesForCurrentThread = GC.GetAllocatedBytesForCurrentThread();
            Debug.WriteLine($"GetStream {lastAllocatedBytesForCurrentThread - allocatedBytesForCurrentThread}");
            allocatedBytesForCurrentThread = lastAllocatedBytesForCurrentThread;

            var tempFolder = @"F:\temp";

            if (!Directory.Exists(tempFolder))
            {
                tempFolder = System.IO.Path.GetTempPath();
            }

            tempFolder = System.IO.Path.Combine(tempFolder, System.IO.Path.GetRandomFileName());
            Directory.CreateDirectory(tempFolder);
            //CompoundFileUnzipper.Unzip(s, tempFolder, byteArrayPool);

            // 为了性能考虑,不再使用内存方式,全部写入到文件
            //var forwardSeekStream = new ForwardSeekStream(s, byteArrayPool);
            var oleFile = System.IO.Path.Combine(tempFolder, System.IO.Path.GetRandomFileName());

            using var oleFileStream = new FileStream(oleFile, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None,
                                                     bufferSize: 4096, FileOptions.RandomAccess);
            s.CopyTo(oleFileStream);
            oleFileStream.Position = 0;

            //Origin(forwardSeekStream);
            var cf = new ReadonlyCompoundFile(oleFileStream);

            lastAllocatedBytesForCurrentThread = GC.GetAllocatedBytesForCurrentThread();
            Debug.WriteLine($"CompoundFile {lastAllocatedBytesForCurrentThread - allocatedBytesForCurrentThread}");
            allocatedBytesForCurrentThread = lastAllocatedBytesForCurrentThread;

            var packageStream = cf.RootStorage.GetStream("Package");

            lastAllocatedBytesForCurrentThread = GC.GetAllocatedBytesForCurrentThread();
            Debug.WriteLine($"GetStream {lastAllocatedBytesForCurrentThread - allocatedBytesForCurrentThread}");
            allocatedBytesForCurrentThread = lastAllocatedBytesForCurrentThread;

            //var tempFolder = @"F:\temp";
            //if (!Directory.Exists(tempFolder))
            //{
            //    tempFolder = System.IO.Path.GetTempPath();
            //}

            var xlsxFile = System.IO.Path.Combine(tempFolder, System.IO.Path.GetRandomFileName() + ".xlsx");

            using (var fileStream = File.OpenWrite(xlsxFile))
            {
                //fileStream.Write(packageStream.GetData().AsSpan());
                cf.CopyTo(packageStream, fileStream);
            }

            //var fakeStream = new FakeStream();
            //cf.CopyTo(packageStream, fakeStream, byteArrayPool);

            //using (var fileStream = File.OpenWrite(xlsxFile))
            //{
            //    fileStream.Write(packageStream.GetData().AsSpan());
            //}
            //using var spreadsheetDocument = SpreadsheetDocument.Open(xlsxFile, false);
            //var sheets = spreadsheetDocument.WorkbookPart!.Workbook.Sheets;

            lastAllocatedBytesForCurrentThread = GC.GetAllocatedBytesForCurrentThread();
            Debug.WriteLine($"CopyTo {lastAllocatedBytesForCurrentThread - allocatedBytesForCurrentThread}");
            allocatedBytesForCurrentThread = lastAllocatedBytesForCurrentThread;



            //// OpenMcdf.CFException:“Cannot load a non-seekable Stream”
            //var compoundFile = new CompoundFile(part.GetStream(FileMode.Open));

            //var oleFile = System.IO.Path.Combine(tempFolder, System.IO.Path.GetRandomFileName());
            //using (var fileStream = File.OpenWrite(oleFile))
            //{
            //    using var stream = part.GetStream(FileMode.Open);
            //    stream.CopyTo(fileStream);
            //}

            //var compoundFile = new CompoundFile(oleFile);
            //var packageStream = compoundFile.RootStorage.GetStream("Package");
            //var xlsxFile = System.IO.Path.Combine(tempFolder, System.IO.Path.GetRandomFileName() + ".xlsx");
            //using (var fileStream = File.OpenWrite(xlsxFile))
            //{
            //    fileStream.Write(packageStream.GetData().AsSpan());
            //}

            using var spreadsheetDocument = SpreadsheetDocument.Open(xlsxFile, false);
            var sheets = spreadsheetDocument.WorkbookPart !.Workbook.Sheets;
        }
Пример #2
0
        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            var file = new FileInfo("Test.pptx");

            using var presentationDocument = PresentationDocument.Open(file.FullName, false);
            var slide = presentationDocument.PresentationPart !.SlideParts.First().Slide;

            var shape = slide.CommonSlideData !.ShapeTree !.GetFirstChild <Shape>() !;

            /*
             *  <p:sp>
             *    <p:nvSpPr>
             *      <p:cNvPr id="4" name="文本框 3" />
             *      <p:cNvSpPr txBox="1" />
             *      <p:nvPr />
             *    </p:nvSpPr>
             *    <p:spPr>
             *      <a:xfrm>
             *        <a:off x="4168346" y="914401" />
             *        <a:ext cx="6096000" cy="3170090" />
             *      </a:xfrm>
             *      <a:prstGeom prst="rect">
             *        <a:avLst />
             *      </a:prstGeom>
             *      <a:noFill />
             *    </p:spPr>
             *    <p:txBody>
             *      <a:bodyPr wrap="square" rtlCol="0">
             *        <a:normAutofit fontScale="60000"/>
             *      </a:bodyPr>
             *      <a:lstStyle />
             *      <a:p>
             *        <a:r>
             *          <a:rPr lang="zh-CN" altLang="en-US" sz="10000">
             *          </a:rPr>
             *          <a:t>一行文本</a:t>
             *        </a:r>
             *        <a:endParaRPr lang="en-US" sz="10000" dirty="0" />
             *      </a:p>
             *    </p:txBody>
             *  </p:sp>
             */
            var shapeProperties = shape.ShapeProperties !;
            var presetGeometry  = shapeProperties.GetFirstChild <PresetGeometry>() !;

            // 这是一个文本框
            Debug.Assert(presetGeometry.Preset?.Value == ShapeTypeValues.Rectangle);
            Debug.Assert(shapeProperties.GetFirstChild <NoFill>() is not null);

            var textBody = shape.TextBody !;

            Debug.Assert(textBody != null);
            var textBodyProperties = textBody.BodyProperties !;

            Debug.Assert(textBodyProperties != null);
            var normalAutoFit = textBodyProperties.GetFirstChild <NormalAutoFit>() !;

            Debug.Assert(normalAutoFit != null);
            Percentage fontScale = normalAutoFit.FontScale is null
                ? Percentage.FromDouble(1)
                : new Percentage(normalAutoFit.FontScale);

            foreach (var paragraph in textBody.Elements <DocumentFormat.OpenXml.Drawing.Paragraph>())
            {
                // 一个文本里面有很多段落
                // 段落里面,文本有不同的样式,如一段可以有不同加粗的文本
                // 相同的样式的文本放在一个 TextRun 里面。不同的样式的文本放在不同的 TextRun 里面

                // 这个文本段落是没有属性的,为了方便样式,就不写代码
                //if (paragraph.ParagraphProperties != null)

                foreach (var run in paragraph.Elements <DocumentFormat.OpenXml.Drawing.Run>())
                {
                    var runProperties = run.RunProperties !;
                    var fontSize      = new PoundHundredfold(runProperties.FontSize !.Value).ToPound();

                    // 默认字体前景色是黑色
                    var text = run.Text !.Text;

                    var textBlock = new TextBlock()
                    {
                        Text                = text,
                        FontSize            = fontSize.ToPixel().Value *fontScale.DoubleValue,
                        FontFamily          = new FontFamily("宋体"),
                        HorizontalAlignment = HorizontalAlignment.Center,
                        VerticalAlignment   = VerticalAlignment.Center,
                    };

                    Root.Children.Add(textBlock);
                }
            }
        }