I am trying to save selected slide so it doesnt retain my source template. how do i retain the existing template while i save the slides
private void SaveSelectedSlide_Click(object sender, RibbonControlEventArgs e)
{
try
{
PowerPoint.Application ppApp = Globals.ThisAddIn.Application;
PowerPoint.SlideRange ppslr = ppApp.ActiveWindow.Selection.SlideRange;
string desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
var temporaryPresentation = Globals.ThisAddIn.Application.Presentations.Add(Microsoft.Office.Core.MsoTriState.msoTrue);
Microsoft.Office.Interop.PowerPoint.CustomLayout customLayout = ppApp.ActivePresentation.SlideMaster.CustomLayouts[Microsoft.Office.Interop.PowerPoint.PpSlideLayout.ppLayoutText];
for (int i = 1; i <= ppslr.Count; i++)
{
var sourceSlide = ppslr[i];
sourceSlide.Copy();
var design = sourceSlide.Design;
temporaryPresentation.Slides.Paste();
}
temporaryPresentation.SaveAs("Temporary", Microsoft.Office.Interop.PowerPoint.PpSaveAsFileType.ppSaveAsPresentation, Microsoft.Office.Core.MsoTriState.msoTrue);
temporaryPresentation.Close();
}
catch (COMException Ex)
{
Debug.WriteLine("Some problem" + Ex.Message + Ex.StackTrace);
MessageBox.Show("PLease enter text ");
}
}
I think I got what you want. When pasting the new slide, save the new SlideRange. Afterwards assign the design of the source slide.
PowerPoint.Application ppApp = Globals.ThisAddIn.Application;
PowerPoint.SlideRange ppslr = ppApp.ActiveWindow.Selection.SlideRange;
string desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
var temporaryPresentation = Globals.ThisAddIn.Application.Presentations.Add(Microsoft.Office.Core.MsoTriState.msoTrue);
Microsoft.Office.Interop.PowerPoint.CustomLayout customLayout = ppApp.ActivePresentation.SlideMaster.CustomLayouts[Microsoft.Office.Interop.PowerPoint.PpSlideLayout.ppLayoutText];
for (int i = 1; i <= ppslr.Count; i++)
{
var sourceSlide = ppslr[i];
sourceSlide.Copy();
var design = sourceSlide.Design;
SlideRange sr = temporaryPresentation.Slides.Paste(); // get newly created slideRange
sr.Design = sourceSlide.Design; // manually set design
}
temporaryPresentation.SaveAs("Temporary", Microsoft.Office.Interop.PowerPoint.PpSaveAsFileType.ppSaveAsPresentation, Microsoft.Office.Core.MsoTriState.msoTrue);
temporaryPresentation.Close();
It worked for me. Please let me know if this is the expected behaviour!
Related
I have an issue when I try to write multiple paragraphs in existing Shape. Only the first paragraph is written. I debug the code and I found that the Shape object as all the paragraphs I want. The problem is when I write to file I found only the first one. I share with you the project code.
class Program
{
public static void Run()
{
string dataDir = ConfigurationManager.AppSettings["directoryToSave"];
string srcDir = ConfigurationManager.AppSettings["Source"];
string appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string file = Path.Combine(appData, srcDir);
using (Presentation presentation = new Presentation(srcDir))
{
IMasterLayoutSlideCollection layoutSlides = presentation.Masters[0].LayoutSlides;
ILayoutSlide layoutSlide = null;
foreach (ILayoutSlide titleAndObjectLayoutSlide in layoutSlides)
{
if (titleAndObjectLayoutSlide.Name == "TITRE_CONTENU")
{
layoutSlide = titleAndObjectLayoutSlide;
break;
}
}
var contenu = File.ReadAllText(#"E:\DemosProject\PF_GEN\PF_GEN\Source\contenu.txt", Encoding.UTF8);
IAutoShape contenuShape = (IAutoShape)layoutSlide.Shapes.SingleOrDefault(r => r.Name.Equals("contenu"));
ITextFrame txt = ((IAutoShape)contenuShape).TextFrame;
txt.Paragraphs.Clear();
string[] lines = contenu.Split(new[] { Environment.NewLine }, StringSplitOptions.None).Where(str => !String.IsNullOrEmpty(str)).ToArray();
for (int i = 0; i < lines.Length; i++)
{
var portion = new Portion();
portion.Text = lines[i];
var paragraphe = new Paragraph();
paragraphe.Portions.Add(portion);
txt.Paragraphs.Add(paragraphe);
}
presentation.Slides.InsertEmptySlide(0, layoutSlide);
presentation.Save(dataDir + "AddLayoutSlides_out.pptx", SaveFormat.Pptx);
}
}
static void Main(string[] args)
{
try
{
var path = ConfigurationManager.AppSettings["sourceAsposeLicensePath"];
License license = new License();
license.SetLicense(path);
Run();
}
catch (Exception ex)
{
Console.WriteLine("Error" + ex.Message);
}
finally
{
Console.WriteLine("Terminated");
Console.ReadKey();
}
}
}
You can find the ppt file (source file) in the attachement file. (https://gofile.io/?c=JpBDS8 1)
Is there any thing missing in my code?
Thanks
I have observed your requirements and suggest you to please try using following sample code on your end. In your sample code, you are adding different paragraphs to a shape inside LayoutSlide and then adding a slide using that LayoutSlide to contain the desired shape. This approach is not correct. You actually need to first add slide based on LayoutSlide and then add text to that shape as per your requirements. The following code will be helpful to you.
public static void RunParaText()
{
string path = #"C:\Aspose Data\";
string dataDir = path;
string srcDir = path + "Master.pptx";
//string appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
//string file = Path.Combine(appData, srcDir);
using (Presentation presentation = new Presentation(srcDir))
{
IMasterLayoutSlideCollection layoutSlides = presentation.Masters[0].LayoutSlides;
ILayoutSlide layoutSlide = null;
foreach (ILayoutSlide titleAndObjectLayoutSlide in layoutSlides)
{
if (titleAndObjectLayoutSlide.Name == "TITRE_CONTENU")
{
layoutSlide = titleAndObjectLayoutSlide;
break;
}
}
var contenu = File.ReadAllText(dataDir+"contenu.txt", Encoding.UTF8);
var slide=presentation.Slides.InsertEmptySlide(0, layoutSlide);
IAutoShape contenuShape = (IAutoShape)slide.Shapes.SingleOrDefault(r => r.Name.Equals("contenu"));
//IAutoShape contenuShape = (IAutoShape)layoutSlide.Shapes.SingleOrDefault(r => r.Name.Equals("contenu"));
ITextFrame txt = ((IAutoShape)contenuShape).TextFrame;
txt.Paragraphs.Clear();
string[] lines = contenu.Split(new[] { Environment.NewLine }, StringSplitOptions.None).Where(str => !String.IsNullOrEmpty(str)).ToArray();
for (int i = 0; i < lines.Length; i++)
{
var portion = new Portion();
portion.Text = lines[i];
var paragraphe = new Paragraph();
paragraphe.Portions.Add(portion);
txt.Paragraphs.Add(paragraphe);
}
//Change font size w.r.t shape size
contenuShape.TextFrame.TextFrameFormat.AutofitType = TextAutofitType.Normal;
presentation.Save(dataDir + "AddLayoutSlides_out.pptx", SaveFormat.Pptx);
}
}
I am working as Support developer/ Evangelist at Aspose.
When i export grid data without grouping it exports perfectly but when i export grid data with grouping it skips rows and if i remove header rows then data is exported perfectly with or without grouping?
I think the problem is in header rows when i remove header rows then it works perfectly.
Please tell me how can i adjust header rows so that grouped data can be exported perfectly
private void btnExport_Click(object sender, EventArgs e)
{
saveFileDialog1.FileName = this.ReportHeaderText.Replace(' ', '-').Replace('/', '-');
saveFileDialog1.OverwritePrompt = true;
if (saveFileDialog1.ShowDialog() != DialogResult.OK)
{
return;
}
if (saveFileDialog1.CheckFileExists)
{
}
if (saveFileDialog1.FileName.Equals(String.Empty))
{
RiceMsgBox.ShowErrorBox("Please enter a file name.");
return;
}
string fileName = this.saveFileDialog1.FileName;
bool openExportFile = false;
RunExportToExcelML(fileName, ref openExportFile);
if (openExportFile)
{
try
{
System.Diagnostics.Process.Start(fileName);
}
catch (Exception ex)
{
RiceMsgBox.ShowErrorBox("The file cannot be opened on your system");
}
}
this.tabControl1.SelectedIndex = 1;
}
private void RunExportToExcelML(string fileName, ref bool openExportFile)
{
Telerik.WinControls.Export.GridViewSpreadExport exporter = new Telerik.WinControls.Export.GridViewSpreadExport(gridReport, 0);
exporter.HiddenColumnOption = Telerik.WinControls.UI.Export.HiddenOption.DoNotExport;
exporter.CellFormatting += exporter_CellFormatting;
exporter.ExportVisualSettings = true;
exporter.SheetMaxRows = ExcelMaxRows._1048576;
exporter.SheetName = System.Text.RegularExpressions.Regex.Replace(this.ReportHeaderText.Length > 30 ? this.ReportHeaderText.Substring(0,30) : this.ReportHeaderText, #"[^0-9a-zA-Z]+", ",");
exporter.SummariesExportOption = SummariesOption.ExportAll;
Telerik.WinControls.Export.SpreadExportRenderer exportRenderer = new Telerik.WinControls.Export.SpreadExportRenderer();
exportRenderer.WorkbookCreated += renderer_WorkbookCreated;
// exportRenderer.ExcelTableCreated += exporter_ExcelTableCreated;
//exporter.CellFormatting += exporter_ExcelCellFormatting;
//FormatGridColumns(gridReport);
try
{
exporter.RunExport(fileName, exportRenderer);
var dialog = RiceMsgBox.GetQuestionBox("The data in the grid was exported successfully. Do you want to open the file?");
if (dialog == DialogResult.Yes)
{
openExportFile = true;
}
else
{
openExportFile = false;
}
}
catch(Exception ex)
{
RiceMsgBox.ShowErrorBox("Error exporting data.");
}
}
void exporter_CellFormatting(object sender, Telerik.WinControls.Export.CellFormattingEventArgs e)
{
CellBorders borders = new CellBorders();
borders.Top = new CellBorder(CellBorderStyle.Thin, new ThemableColor(System.Windows.Media.Colors.Black));
borders.Bottom = new CellBorder(CellBorderStyle.Thin, new ThemableColor(System.Windows.Media.Colors.Black));
borders.Right = new CellBorder(CellBorderStyle.Thin, new ThemableColor(System.Windows.Media.Colors.Black));
borders.Left = new CellBorder(CellBorderStyle.Thin, new ThemableColor(System.Windows.Media.Colors.Black));
e.CellStyleInfo.Borders = borders;
}
void renderer_WorkbookCreated(object sender, Telerik.WinControls.Export.WorkbookCreatedEventArgs e)
{
PatternFill solidPatternFill = new PatternFill(PatternType.Solid, System.Windows.Media.Colors.Transparent, System.Windows.Media.Colors.Transparent);
CellValueFormat textFormat = new CellValueFormat("#");
string dateRange = "( From Date : " + dtpFromDate.Text + " - To Date : " + dtpToDate.Text + " )";
Worksheet worksheet = e.Workbook.Sheets[0] as Worksheet;
worksheet.Columns[worksheet.UsedCellRange].AutoFitWidth();
CellRange range = new CellRange(0, 0, 1, gridReport.Columns.Count);
CellSelection header = worksheet.Cells[range];
if (header.CanInsertOrRemove(range, ShiftType.Down))
{
header.Insert(InsertShiftType.Down);
}
header.Merge();
header.SetFormat(textFormat);
header.SetHorizontalAlignment(Telerik.Windows.Documents.Spreadsheet.Model.RadHorizontalAlignment.Center);
header.SetVerticalAlignment(Telerik.Windows.Documents.Spreadsheet.Model.RadVerticalAlignment.Center);
header.SetFontFamily(new ThemableFontFamily("Rockwell"));
header.SetFontSize(24);
header.SetFill(solidPatternFill);
header.SetValue(this.ReportHeaderText);
}
The GridViewSpreadExport generates a document that consists of merged cells. Inserting a row on the top and then exporting the document causes wrong merged cells. It is a known issue: link
As a workaround, instead of using the WorkbookCreated event to insert a new row you can export the document and then reopen it and insert a row above the exported grid data.
private void RunExportToExcelML(string fileName, ref bool openExportFile)
{
Telerik.WinControls.Export.GridViewSpreadExport exporter = new Telerik.WinControls.Export.GridViewSpreadExport(gridReport, 0);
exporter.HiddenColumnOption = Telerik.WinControls.UI.Export.HiddenOption.DoNotExport;
exporter.CellFormatting += exporter_CellFormatting;
exporter.ExportVisualSettings = true;
exporter.SheetMaxRows = ExcelMaxRows._1048576;
exporter.SheetName = System.Text.RegularExpressions.Regex.Replace(this.ReportHeaderText.Length > 30 ? this.ReportHeaderText.Substring(0, 30) : this.ReportHeaderText, #"[^0-9a-zA-Z]+", ",");
exporter.SummariesExportOption = SummariesOption.ExportAll;
Telerik.WinControls.Export.SpreadExportRenderer exportRenderer = new Telerik.WinControls.Export.SpreadExportRenderer();
//exportRenderer.WorkbookCreated += renderer_WorkbookCreated;
try
{
exporter.RunExport(fileName, exportRenderer);
this.InsertHeader(fileName);
// more code...
}
private void InsertHeader(string fileName)
{
XlsxFormatProvider formatProvider = new XlsxFormatProvider();
Workbook workbook = null;
using (Stream stream = new FileStream(fileName, FileMode.Open))
{
workbook = formatProvider.Import(stream);
}
PatternFill solidPatternFill = new PatternFill(PatternType.Solid, System.Windows.Media.Colors.Transparent, System.Windows.Media.Colors.Transparent);
CellValueFormat textFormat = new CellValueFormat("#");
//string dateRange = "( From Date : " + dtpFromDate.Text + " - To Date : " + dtpToDate.Text + " )";
Worksheet worksheet = workbook.Sheets[0] as Worksheet;
worksheet.Columns[worksheet.UsedCellRange].AutoFitWidth();
CellRange range = new CellRange(0, 0, 1, gridReport.Columns.Count);
CellSelection header = worksheet.Cells[range];
if (header.CanInsertOrRemove(range, ShiftType.Down))
{
header.Insert(InsertShiftType.Down);
}
header.Merge();
header.SetFormat(textFormat);
header.SetHorizontalAlignment(Telerik.Windows.Documents.Spreadsheet.Model.RadHorizontalAlignment.Center);
header.SetVerticalAlignment(Telerik.Windows.Documents.Spreadsheet.Model.RadVerticalAlignment.Center);
header.SetFontFamily(new ThemableFontFamily("Rockwell"));
header.SetFontSize(24);
header.SetFill(solidPatternFill);
header.SetValue(this.ReportHeaderText);
using (Stream output = new FileStream(fileName, FileMode.Create))
{
formatProvider.Export(workbook, output);
}
}
For more information about SpreadProcessing visit the following link: https://docs.telerik.com/devtools/document-processing/libraries/radspreadprocessing/overview
Good Afternoon everyone. I have a question involving taking data in a tablelayoutpanel and placing it into a .pdf using iTextSharp (Unless someone knows a better technology). The tableLayout panel consists of 1 column with 1 row by default and has rows dynamically added given what the data returns.
Here is what I have for printing:
private void btnPrint_Click(object sender, EventArgs e)
{
try
{
SaveFileDialog dialog = new SaveFileDialog();
dialog.Title = "Save file as...";
dialog.Filter = "Pdf File |*.pdf";
if (dialog.ShowDialog() == DialogResult.OK)
{
Document doc = new Document(PageSize.LETTER);
PdfWriter writer = PdfWriter.GetInstance(doc, new FileStream(dialog.FileName, FileMode.Create));
doc.Open();
Paragraph entry1 = new Paragraph("Hello World!");
//Page 1 Printing
PdfPTable LegendsForTable = new PdfPTable(this.tblPnlLayLFT.ColumnCount);
doc.Add(entry1);
doc.Close();
MessageBox.Show("File saved");
}
}
catch (Exception exception)
{
MessageBox.Show(#"ERROR: Issue encountered while trying to print. " + Environment.NewLine
+ #"Contact ITSupport with the following the following error" + Environment.NewLine
+ exception);
}
}
Does anyone know a method to copy tablelayoutpanel to .pdf?
I was able to figure this out myself.
Step 1 was to create a loop that iterates through the table layout panels and place the order that I want into a list.
int reIterator = 1;
int replicateIterator = 1;
List<string> table1List = new List<string>();
for (int counter = 0; counter < 6; counter++)
{
while (reIterator < 7)
{
string currentLabel = "LblRE" + reIterator + "R" + replicateIterator;
Label reLabel = this.Controls.Find(currentLabel, true).FirstOrDefault() as Label;
if (reLabel.Text != null)
{
table1List.Add(reLabel.Text);
reIterator = reIterator + 1;
}
else
{
table1List.Add(reLabel.Text = "");
reIterator = reIterator + 1;
}
}
//Builds next row
if (reIterator == 7)
{
replicateIterator = replicateIterator + 1;
reIterator = 1;
}
}
Then using iTextSharp I am able to loop through using the list and add the data to a PDF.
Is it possible to get slide html of PPT in C#.
and also how can we crate new slide using html while creating presentation using interop?
You can read from PPT file and get the text out of each slide, see below for an example :
static void Main(string[] args)
{
Microsoft.Office.Interop.PowerPoint.Application PowerPoint_App = new Microsoft.Office.Interop.PowerPoint.Application();
Microsoft.Office.Interop.PowerPoint.Presentations multi_presentations = PowerPoint_App.Presentations;
Microsoft.Office.Interop.PowerPoint.Presentation presentation = multi_presentations.Open(#"C:\PPT\myPowerpoint.pptx");
string presentation_text = "";
for (int i = 0; i < presentation.Slides.Count; i++)
{
foreach (var item in presentation.Slides[i+1].Shapes)
{
var shape = (PowerPoint.Shape)item;
if (shape.HasTextFrame == MsoTriState.msoTrue)
{
if (shape.TextFrame.HasText == MsoTriState.msoTrue)
{
var textRange = shape.TextFrame.TextRange;
var text = textRange.Text;
presentation_text += text+" ";
}
}
}
}
PowerPoint_App.Quit();
Console.WriteLine(presentation_text);
}
I have a block of code which reads powerpoint slides and creates xml for them.Everything is working fine on my local machine.but on server,when second slide is read.I Get the exception:
EXCEPTION:The message filter indicated that the application is busy. (Exception from HRESULT: 0x8001010A (RPC_E_SERVERCALL_RETRYLATER)) for Powerpoint Interop
Function Throwing Error:
public string AddPPTPages(long templateid, long pptFileId)
{
string strPptFilePath = "";
string strSuccess = "";
using (var dc = new DataContext())
{
var template = dc.Templates.GetByID(templateid);
template.ExtendedData = "<template><pptfileid>" + pptFileId + "</pptfileid></template>";
template.Save();
dc.SubmitChanges();
var file = dc.FileHandles.GetByID(Convert.ToInt64(pptFileId));
file.EnsureUrlFiles();
strPptFilePath = file.GetPhysicalPath(file.FileName);//get path of original ppt file
}
try
{
using (new Impersonator(Installs.Current.PPTUser, null, Installs.Current.PPTPassword))
{
PowerPoint.Application PowerPoint_App = new PowerPoint.Application();//Open PowerPoint app/process
PowerPoint.Presentation presentation = null;//initialize presentation to null
try
{
PowerPoint_App.Visible = MsoTriState.msoTrue;//set app visibility to true
presentation = PowerPoint_App.Presentations.Open(strPptFilePath, Microsoft.Office.Core.MsoTriState.msoFalse, Microsoft.Office.Core.MsoTriState.msoFalse, Microsoft.Office.Core.MsoTriState.msoTrue);//open powerpoint presentation using path strPptFilePath
templateID = templateid;//required for readslide function
/////////ERROR is THROWN FOR BELOW LINE//////////////////
for (int i = 0; i < presentation.Slides.Count; i++)
{
ReadSlides(presentation, i);//call to read current slide
}
using (var dc = new DataContext())
{
var template = dc.Templates.GetByID(templateID);
template.FixPageIndexes();
template.Save();
dc.SubmitChanges();
}
presentation.Close();//close presentation
PowerPoint_App.Quit();//quit opened powerpoint app/process
}
catch (Exception ex)
{
strSuccess = ex.ToString();
}
finally
{
while (Marshal.FinalReleaseComObject(presentation) != 0) { }
presentation = null;
while (Marshal.FinalReleaseComObject(PowerPoint_App) != 0) { }
PowerPoint_App = null;
GC.Collect();
GC.WaitForPendingFinalizers();
KillPPTProcess();//find ppt process in taskmanager and kill it
}
}
}
catch (Exception e)
{
strSuccess = e.ToString();
MindMatrix.Libraries.Entities.ExceptionMessage.HandleException(e, null);
Loggers.HandleException2(e);
}
return strSuccess;
}
private void ReadSlides(PowerPoint.Presentation presentation, int i)
{
try
{
string strPptXml = "";
//get number of objects(text and image) present in current slide
foreach (var item in presentation.Slides[i + 1].Shapes)
{
var shape = (PowerPoint.Shape)item;
strPptXml += ReadShape(shape);//read object and add it to xml
}
int height = ConvertToPixel(presentation.Slides[i + 1].Master.Height);//get height of current slide
int width = ConvertToPixel(presentation.Slides[i + 1].Master.Width);//get width of current slide
strFileImage = Installs.Current.GetTempDirectory(DirectoryType.PPT);//get the temporary folder path for current loggedin user in machine
if (System.IO.Directory.Exists(strFileImage) == false)
{
System.IO.Directory.CreateDirectory(strFileImage);
}
strFileImage = strFileImage + "\\" + (i + 1) + ".png";//create image path for slide snapshot
presentation.Slides[i + 1].Export(strFileImage, "png", width, height);//create snapshot as png image to temp folder
strPptXml = "<slides datasourceid='0' repeaterid = '0' id='" + presentation.Slides[i + 1].SlideID + "' >" + strPptXml + "</slides>";//create slide xml using slideid and ppt xml(contains text and image objects of slide)
MemoryStream ms = new MemoryStream();
System.Drawing.Image imageIn;
imageIn = System.Drawing.Image.FromFile(strFileImage);//Creates an Image from location strFileImage.
imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
using (var dc = new DataContext())
{
var template = dc.Templates.GetByID(templateID);
//template.createPptPage(strPptXml, height, width, ms);//call to create ppt page for current slide
template.createPptPage(RemoveTroublesomeCharacters(strPptXml), height, width, ms);//call to create ppt page for current slide
dc.SubmitChanges();
}
}
catch (Exception e)
{
Loggers.HandleException2(e);
}
}
Any help guys??
My guess is that ReadSlides is changing the value of presentation.Slides.Count. This would happen if you were adding slides to, or removing slides from your presentation within ReadSlides.
I would pull this out into it's own variable and then use this variable in your for loop, like so:
var slideCount = presentation.Slides.Count;
for (int i = 0; i < slideCount; i++)
{
//etc etc
Have you tried setting DisplayAlert to false?
PowerPoint_App.DisplayAlerts = Powerpoint.PpAlertLevel.ppAlertsNone
You normally get this exception when Office opens a dialogue, and your application is unable to continue.
Quoting from your question:
Everything is working fine on my local machine.but on server,when second slide is read.I Get the exception
If your app is truly running in an unattended server environment, be aware that Microsoft specifically does not support COM for Office. Their warnings are fairly explicit. Here's a snippet:
If you use an Office application from a server-side solution, the application will lack many of the necessary capabilities to run successfully. Additionally, you will be taking risks with the stability of your overall solution.