How to Add PPTX Slide Content to an Aspose.Words Document and Then Convert It to PDF in C#?

hi,

I am developing quite a complex logic:
I am having multiple sources of documents ( fill in a coversheet, add sharepoint documents, fill in html template with data) that needs be collated and converted to a pdf. I have already a solution: cloning the coversheet to a final document( to maintain its styles & fonts) and then download the Sharepoint documents and add them to the final document. Everything is fine, but when adding pptx slides, I don’t know what approach should I use; I need to preserve the slides format as they are originally (style, font, orientation, images, having text selectable). Should I treat each slide differently? depending if it contains images or text?
Please help.

@taianata

Can you please specify how you are currently adding the PPTX slides to the Aspose Word Document? Are you using any specific Aspose libraries for this process?

sure; I am using this code:

  public static Document ConvertPptxToWordDocument(Stream pptxInputStream)
  {
      var pptxStream = CloneToMemoryStream(pptxInputStream);

      using var pres = new Presentation(pptxStream);

      float slideWidthPx = pres.SlideSize.Size.Width;
      float slideHeightPx = pres.SlideSize.Size.Height;
      double slideWidthPt = ConvertUtil.PixelToPoint(slideWidthPx);
      double slideHeightPt = ConvertUtil.PixelToPoint(slideHeightPx);

      var finalDoc = new Document();
      var builder = new DocumentBuilder(finalDoc);

      for (int i = 0; i < pres.Slides.Count; i++)
      {
          var slide = pres.Slides[i];

          bool hasText = SlideContainsText(slide);
          bool hasImages = SlideContainsImages(slide);


          if (hasText && !hasImages)
          {
              // Text only: convert slide PDF to Word (selectable text)
              using var slidePdfStream = new MemoryStream();
              using (var singleSlidePres = new Presentation())
              {
                  singleSlidePres.Slides.RemoveAt(0);
                  //singleSlidePres.Slides.AddClone(slide);
                  singleSlidePres.Save(slidePdfStream, Aspose.Slides.Export.SaveFormat.Pdf);
                  slidePdfStream.Position = 0;
              }

              var slideDoc = new Document(slidePdfStream);

              // Set page setup for each section in slideDoc
              foreach (Aspose.Words.Section sec in slideDoc.Sections)
              {
                  sec.PageSetup.PageWidth = slideWidthPt;
                  sec.PageSetup.PageHeight = slideHeightPt;
                  sec.PageSetup.Orientation = Aspose.Words.Orientation.Landscape;
               
              }

              finalDoc.AppendDocument(slideDoc, ImportFormatMode.KeepSourceFormatting);
              builder.MoveToDocumentEnd();
          }
          else if (!hasText && hasImages)
          {
              // Image only: insert rendered slide image inline
              using var bmp = slide.GetThumbnail(2.0f, 2.0f);
              using var msImage = new MemoryStream();
              bmp.Save(msImage, System.Drawing.Imaging.ImageFormat.Png);
              //msImage.Position = 0;

              // Setup page size for landscape
              builder.PageSetup.PageWidth = slideWidthPt;
              builder.PageSetup.PageHeight = slideHeightPt;
              builder.PageSetup.Orientation = Aspose.Words.Orientation.Landscape;
             
              builder.InsertImage(msImage, slideWidthPt, slideHeightPt);
          }
          else if (hasText && hasImages)
          {
              // Both text and images: Import PDF + overlay image for fidelity

              using var slidePdfStream = new MemoryStream();
              using (var singleSlidePres = new Presentation())
              {
                  singleSlidePres.Slides.RemoveAt(0);
                  singleSlidePres.Slides.AddClone(slide);
                  singleSlidePres.Save(slidePdfStream, Aspose.Slides.Export.SaveFormat.Pdf);
                  slidePdfStream.Position = 0;
              }

              var slideDoc = new Document(slidePdfStream);

              // Set page setup for each section in slideDoc
              foreach (Aspose.Words.Section sec in slideDoc.Sections)
              {
                  sec.PageSetup.PageWidth = slideWidthPt;
                  sec.PageSetup.PageHeight = slideHeightPt;
                  sec.PageSetup.Orientation = Aspose.Words.Orientation.Landscape;
                  sec.PageSetup.TopMargin = 0;
                  sec.PageSetup.BottomMargin = 0;
                  sec.PageSetup.LeftMargin = 0;
                  sec.PageSetup.RightMargin = 0;
              }

              finalDoc.AppendDocument(slideDoc, ImportFormatMode.KeepSourceFormatting);

              builder.MoveToSection(finalDoc.Sections.Count - 1);
              builder.MoveToDocumentEnd();

              using var bmp = slide.GetThumbnail(2.0f, 2.0f);
              using var msImage = new MemoryStream();
              bmp.Save(msImage, System.Drawing.Imaging.ImageFormat.Png);
              msImage.Position = 0;

              var shape = builder.InsertImage(msImage);
              shape.WrapType = WrapType.None;
              shape.RelativeHorizontalPosition = RelativeHorizontalPosition.Page;
              shape.RelativeVerticalPosition = RelativeVerticalPosition.Page;
              shape.Left = 0;
              shape.Top = 0;
              shape.Width = slideWidthPt;
              shape.Height = slideHeightPt;
          }

      }

      return finalDoc;
  }

  private static bool SlideContainsText(ISlide slide)
  {
      foreach (var shape in slide.Shapes)
      {
          if (shape is IAutoShape autoShape)
          {
              if (autoShape.TextFrame != null && !string.IsNullOrWhiteSpace(autoShape.TextFrame.Text))
                  return true;
          }
      }
      return false;
  }

  private static bool SlideContainsImages(ISlide slide)
  {
      foreach (var shape in slide.Shapes)
      {
          if (shape is IPictureFrame)
              return true;
      }
      return false;
  }
  private static MemoryStream CloneToMemoryStream(Stream input)
  {
      var ms = new MemoryStream();
      input.CopyTo(ms);
      ms.Position = 0;
      return ms;
  }

hi, I m using Aspose Slides and Aspose Word. Trying to add slides to a Aspose Word document and then convert the whole document to pdf.

@taianata

We are moving this inquiry to Aspose.Slides category where you will be assisted shortly.

Usually, presentation slides can be converted to PDF pages using Aspose.Slides regardless of the slide content. Could you please elaborate on the issues you encountered?

hi, thanks for helping me out.
My requirement is to generate a collated pdf by having a coversheet (a docx template is used), inserted sharepoint documents ( docx/pptx that are downloaded as stream using graph ) and then a closure note is added in the end of the document (html template is used).
The technical approach is to use a final document that is a clone of the coversheet on which I add documents; The issue with the pptx is slides is the fact that when adding them and converting them to the final document, depending in the approach the following things happens:

  • the text is selectable and the images Not are rendered, but the final pdf does respects the slides format /orientation as landscape and styles: So I understood that When you save a PowerPoint presentation to PDF and then load that PDF using Aspose.Words, only selectable text and vector elements are imported. Images, backgrounds, and complex visual formatting are often lost or ignored.
  private static Document BuildDocumentFromPresentation(DocumentStreamDetails stream)
  {
      MemoryStream pdfFromPptStream = new();
      MemoryStream documentStream = new();

      Presentation presentation = BuildSeakablePresentation(stream.FileContent);
      presentation.Save(pdfFromPptStream, global::Aspose.Slides.Export.SaveFormat.Pdf);

      pdfFromPptStream.Seek(0, SeekOrigin.Begin);

      Document doc = new(pdfFromPptStream);

      doc.Save(documentStream, SaveFormat.Doc);
      documentStream.Seek(0, SeekOrigin.Begin);

      pdfFromPptStream.Close();
      documentStream.Close();

      return doc;
  }

  private static Presentation BuildSeakablePresentation(Stream stream)
  {
      MemoryStream memoryStream = BuildMemoryStream(stream);

      return new Presentation(memoryStream);
  }

  private static MemoryStream BuildMemoryStream(Stream stream)
  {
      if (stream is MemoryStream memoryStream)
      {
          return memoryStream;
      }

      MemoryStream newMemoryStream = new();
      stream.CopyTo(newMemoryStream);
      newMemoryStream.Seek(0, SeekOrigin.Begin);

      return newMemoryStream;
  }
  • the images are rendered, but the text is not selectable by using this solution:
 private static Document BuildDocumentFromPresentation(DocumentStreamDetails pptxStream)
 {
     var doc = new Document();
     var builder = new DocumentBuilder(doc);

     using (var presentation = new Presentation(pptxStream.StreamFileContent))
     {
         float slideWidthPx = presentation.SlideSize.Size.Width;
         float slideHeightPx = presentation.SlideSize.Size.Height;

         // Convert slide dimensions from pixels to points (Aspose uses points for page size)
         double slideWidthPt = ConvertUtil.PixelToPoint(slideWidthPx);
         double slideHeightPt = ConvertUtil.PixelToPoint(slideHeightPx);

         int slideIndex = 0;
         foreach (var slide in presentation.Slides)
         {
             // Set page size to match slide size
             var section = builder.CurrentSection;
             section.PageSetup.Orientation = Aspose.Words.Orientation.Landscape;
             section.PageSetup.PageWidth = slideWidthPt;
             section.PageSetup.PageHeight = slideHeightPt;

             // Remove margins so image fits exactly
             section.PageSetup.TopMargin = 0;
             section.PageSetup.BottomMargin = 0;
             section.PageSetup.LeftMargin = 0;
             section.PageSetup.RightMargin = 0;

             // Render slide to high-quality image
             using (var image = slide.GetImage(2.0f, 2.0f)) // 2.0f = higher DPI
             using (var ms = new MemoryStream())
             {
                 image.Save(ms, Aspose.Slides.ImageFormat.Png);
                 ms.Position = 0;

                 var shape = builder.InsertImage(ms);
                 shape.WrapType = WrapType.Inline;

                 // Set image size to page dimensions in points
                 shape.Width = slideWidthPt;
                 shape.Height = slideHeightPt;
             }

             // If not last slide, insert section break
             if (++slideIndex < presentation.Slides.Count)
             {
                 builder.InsertBreak(BreakType.SectionBreakNewPage);
             }
         }
     }

     return doc;
 }

@taianata,
Thank you for the issue description. We need more detail to investigate the case. Please share the following files and information:

  • sample presentation file
  • output PDF and Word files
  • OS version on which the code was executed
  • .NET target platform in your application project
  • Aspose.Slides and Aspose.Words versions you are using
1 Like

input
test.pdf (845.3 KB)

output
output.pdf (42.2 KB)

  • OS version on which the code was executed: win11
  • .NET target platform in your application project .NET 8
  • Aspose.Slides and Aspose.Words versions you are using : Aspose total ; Aspose Slides 25.3.0, Aspose.Words 25.3.0

code executed:


MemoryStream pdfFromPptStream = new();
MemoryStream documentStream = new();

Presentation presentation = BuildSeakablePresentation(pptxStream.StreamFileContent);
presentation.Save(pdfFromPptStream, global::Aspose.Slides.Export.SaveFormat.Pdf);

pdfFromPptStream.Seek(0, SeekOrigin.Begin);

Document doc = new(pdfFromPptStream);

doc.Save(documentStream, SaveFormat.Doc);
documentStream.Seek(0, SeekOrigin.Begin);

pdfFromPptStream.Close();
documentStream.Close();

return doc; 

@taianata,
Thank you for the details. Could you please also share the presentation file you used?

I would to do so, but I am not allowed the upload pptx, so I attched the slides as pdf (test.pdf file) thanks

@taianata,
You can zip the presentation file and upload the archive here. Alternatively, you can share a link to the file hosted on a file storage service (Google Drive, Dropbox, etc.).