Is there a way to take an image of an excel file without using office.interop dlls ?
I succeeded to embed an excel file into a word document, but i need to show an image of this excel file on the word document. Using filestream, i can read any image and embed into the word document using open xml. The last thing who rest is creating an image from an excel file.
SpreadsheetGear 2012 for .NET can do that:
using SpreadsheetGear;
...
// Open workbook (SpreadsheetGear supports both XLS and XLSX/XLSM file formats)
IWorkbook workbook = Factory.GetWorkbook(#"C:\path\to\workbook.xlsx");
IWorksheet worksheet = workbook.Worksheets["Sheet1"];
// Create Image class, passing in desired range to render
SpreadsheetGear.Drawing.Image image = new SpreadsheetGear.Drawing.Image(worksheet.Cells["A1:D10"]);
// Create Bitmap of range
System.Drawing.Bitmap bitmap = image.GetBitmap();
// ... Insert into Word ...
The Image class also accepts IShape and IChart objects if you wish to render images of those objects instead. Once you have a System.Drawing.Bitmap you can presumably do whatever you want with it, including inserting into a Word document. You can find additional samples on the Excel Chart and Range Imaging Samples page.
Disclaimer: I work for SpreadsheetGear.
Related
I need to insert an enhanced meta file image (.emf) to my worksheet. The image has to scale without losing resolution that's why I'm using emf format.
I've tried inserting the image from a memory stream and reading from a file, but somewhere during the process the emf is converted to jpg and no longer scales as the spreadhseet is viewed/printed in different sizes.
Note, when I use Interop.Excel the image inserts as an emf file and scales appropriately. It's when I use EPPlus that I have the problem. I really want to get away from Interop.Excel thought, that's why I'm using EPPlus.
// This works as expected, but I don't want to use the interop lib.
using Excel = Microsoft.Office.Interop.Excel;
myXlWorkBook.ActiveSheet.shapes.AddPicture(emfImageFileName, ....);
// This does not. The picture appears in the worksheet but does not scale.
using OfficeOpenXml;
using OfficeOpenXml.Drawing;
ExcelPicture pic = myXlWorkSheet.Drawings.AddPicture("Picture Name", new FileInfo(emfImageFileName));
// This doesn't work either.
Image img = Image.FromStream(myEmfImageStream);
ExcelPicture pic = myXlWorkSheet.Drawings.AddPicture("Picture Name", img);
My expected result should be an Excel worksheet with my image in it that scales properly when viewed/printed in various sizes.
Make sure you give it dimensions otherwise everything will be zero:
pic.From.Row = 0;
pic.From.Column = 0;
pic.To.Row = 30;
pic.To.Column = 23;
As for storing as a JPG, that sounds very strange, it should not randomly convert. You can confirm if it is or not by opening the XLSX file in 7-zip or rename to .ZIP and open. You should see the file stored in the media folder.
Also, watch for spaces in the emf file name as I have seen that trip up EPPlus.
UPDATE
For anyone who might come across this, it is a bug with Epplus. I have submitted a PR"
https://github.com/JanKallman/EPPlus/issues/496
I have a VSTO addin that receives an excel chart (in byte array) over a network from a server. I would like to paste this chart onto a powerpoint slide programmatically without having to save the chart to disk first.
However, when I look through all the .Add* methods exposed by Microsoft.Office.Interop.PowerPoint.Shapes, they all seem to require a file path in string . In other words, I would have to convert the binary data to a file in a supported format on the system and get its path before I can use those functions.
Are there any way to directly use this binary data and paste it on the powerpoint slide without having to save it as a file on the system first?
using Microsoft.Office.Interop.Excel;
void CreateChart()
{
ChartData gChartData;
Workbook gWorkBook;
Worksheet gWorkSheet;
// Create the chart and set a reference to the chart data.
var myChart = ActivePresentation.Slides[1].Shapes.AddChart() as Microsoft.Office.Interop.PowerPoint.Chart;
gChartData = myChart.ChartData;
// Set the Workbook and Worksheet references.
gWorkBook = gChartData.Workbook;
gWorkSheet = gWorkBook.Worksheets[1];
// Add the data to the workbook.
gWorkSheet.ListObjects["Table1"].Resize(gWorkSheet.Range["A1:B5"]);
gWorkSheet.Range["Table1[[#Headers],[Series 1]]"].Value = "Items";
gWorkSheet.Range["a2"].Value = "Coffee";
gWorkSheet.Range["a3"].Value = "Soda";
gWorkSheet.Range["a4"].Value = "Tea";
gWorkSheet.Range["a5"].Value = "Water";
gWorkSheet.Range["b2"].Value = "1000";
gWorkSheet.Range["b3"].Value = "2500";
gWorkSheet.Range["b4"].Value = "4000";
gWorkSheet.Range["b5"].Value = "3000";
//ToDo: Style
}
fill the data as you like (you may fill it with a for loop and fill the $"a{i}" column with the number of the entry (i))
See this Article for further Information
UPDATE 21.04.2021:
This isn't what the OP asked for.
In his comment he said:
Even if it is in a text format, I would still have trouble pasting it directly onto the slide because all the methods to embed onto PowerPoint slide exposed by Microsoft.Office.Interop.PowerPoint.Shapes only accept the path of the file in string-not the file itself-as its parameter to access the required file... if I'm not mistaken.
This is not correct. I pointed out a way to create charts programmatically without having to create an excel sheet an save it somewhere.
If you would have gotten the data in a defined format (e.g. json) you could use my code to generate the chart.
But now what you seem to be waiting for:
If you click copy with and excel-chart selected, then open your PowerPoint presentation, set your selection where your want the chart to be and paste the chart, it will be inserted there no problem.
But how can I sent this Data and then paste it?
The Excel-Chart has got a method to copy itself:
https://learn.microsoft.com/de-de/office/vba/api/excel.chart(object)
Convert the data in your clipboard to binary data
Send the data
Convert the data back and store it in your clipboard
Use the TextRange of your Powerpoint-Selection to paste the data
https://learn.microsoft.com/de-de/office/vba/api/powerpoint.textrange
I am trying to automate a Powerpoint presentation. I am using OpenXML to navigate the powerpoint presentation up to the point that I find the Excel linked to a chart. Now I want to use EPPlus to load a datatable into one of the worksheets (because EPPlus has a simple LoadFromDataTable function whereas I think I would have to write lots of code to use OpenXML).
So my problem is this.
I have a PresentationDocument in memory. And I have navigated to the particular chart that I want to manipulate via:
doc.PresentationPart.SlideParts.ElementAt(0).ChartParts.ElementAt(0)
I get the Excel part using:
var stream = chartpart.EmbeddedPackagePart.GetStream()
Then I tried:
using(var pck = new ExcelPackage(stream)) {
`do stuff;
`pck.Save();
}
and then at the end I do a doc.PresentationPart.Presentation.Save but this hasn't changed the Presentation. I can change it using OpenXML instead with:
using (var xl = Spreadsheet.Document.Open(stream, true))
{
`do stuff;
`xl.Close();
}
With everything else the same. So I guess either xl.Close() is doing stuff that pck.Save() isn't or I am using the stream incorrectly - can anyone advise?
I've been working on an application to read images from multiple word files and store them in one single word file using Microsoft.Office.Interop.Word in C#
EDIT: I also need to save a copy of the images on the file system, so I need the image in a Bitmap or similar object.
This is my implementation so far, which works fine:
foreach (InlineShape shape in doc.InlineShapes)
{
shape.Range.Select();
if (shape.Type == WdInlineShapeType.wdInlineShapePicture)
{
doc.ActiveWindow.Selection.Range.CopyAsPicture();
ImageData = Clipboard.GetDataObject();
object _ob1 = ImageData.GetData(DataFormats.Bitmap);
bmp = (Bitmap)_ob1;
images[i++] = bmp;
/*
bmp.Save("C:\\Users\\Akshay\\Pictures\\bitmaps\\test" + i.ToString() + ".bmp");
*/
}
}
I have:
Selected the images as InlineShapes
Copied the shape into Clipboard
Stored the shape in the Clipboard in a DataObject
Extracted the shape from the DataObject in Bitmap format and stored in a Bitmap object.
I've been told to refrain from using Clipboard in Word automation and use the Word APIs instead.
I've read up on it and found an SO answer stating the same.
I looked up many implementations of reading images from Word files on MSDN, SO etc. but could not find any without using clipboard.
How do I read images from Word files using the Word APIs from Microsoft.Office.Interop.Word namespace alone without using Clipboard ?
Word documents in the Office Open XML file format store images in Base64. So it should be possible to extract that information and convert/stream it to a file. You can access the information when the document is open in the Word application using the Range.WordOpenXML property.
string shapeBase64 = shape.Range.WordOpenXML;
This will return the entire Word Open XML in the flat file OPC format. In other words, it won't contain only the picture in Base64, but the entire zip package definition as XML that surrounds it. In my quick test, the tag the contains the actual Base64 is
<pkg:binaryData>
That's a child element of
<pkg:part pkg:name="/word/media/image1.jpg" pkg:contentType="image/jpeg" pkg:compression="store">
Note that it would also be possible for you to get the entire document's WordOpenXML in one step:
document.Content.WordOpenXML
but might then need to understand the way the InlineShapes in the document body are linked to the actual information in the "media" part.
And it would be possible, of course, to work directly with the Zip Package (using the Open XML SDK, perhaps) instead of opening the document in the Word.Application.
I have a requirement to generate a PDF from multiple different (Unknown page Sized PDF's)
Create a cover sheet from a template and write the text onto it.
Pull a PDF (Unknown page size) and append to the above 3) Repeat
until all required PDF's are attached
Step 1 is not a problem and this is working, so I have a a cover sheet PDF generated. I now need a way to append the additional PDF's as above. How can we achieve this using ITextSharp?
If you are trying to concatenate multiple PDF files into one you may take a look at the following post.
I found a simple way to do this, I found something called PDFCopy in ITextSharp
void MergePdfStreams(List<Stream> Source, Stream Dest)
{
var copy = new PdfCopyFields(Dest);
foreach (Stream source in Source)
{
var reader = new PdfReader(source);
copy.AddDocument(reader);
}
copy.Close();
}
Source : Is there a straight forward way to append one PDF doc to another using iTextSharp?