is it possible to create an image that will load via URL with EPPlus? - epplus

I need to embed images into an Excel spreadsheet using EEPlus. There 1000's of rows, so embedding these as Pictures is not an option since this file gets generated via a website and the file would be huge and slow to create.
It would be nice if there were a way to set the URL of an image and have it load when the document is opened. Is this possible?

If you are staying within the confines of excel, the only way I can think of doing it is with using vba with something like this:
How to get images to appear in Excel given image url.
Can then have it resave itself as non-macroed workbook. Something like this:
//add the macro to call sub that applies the url on open
workbook.Worksheets.Add("newworksheet");
var sb = new StringBuilder();
sb.AppendLine("Private Sub Workbook_SheetCalculate(ByVal Sh As Object)");
sb.AppendLine(" ApplyUrlsSub");
sb.AppendLine(" Application.DisplayAlerts = False");
sb.AppendLine(String.Format(" ActiveWorkbook.SaveAs \"{0}\", xlOpenXMLWorkbook", file.FullName.Replace("xlsm", "xlsx")));
sb.AppendLine(" Application.DisplayAlerts = True");
sb.AppendLine("End Sub");
pck.Workbook.CreateVBAProject();
pck.Workbook.CodeModule.Code = sb.ToString();
(adpated from: EPPlus Pivot Table - Copy Values to New Sheet)
But the user still needs to enable allowing the initial xlsm to run with macros which sould be a problem is there are security concerns.

Related

Automaticaly open xls file on program start?

To provide our users to edit excel files without ms excel, we have made a simple app with visual studio 2012 and devexpress Spreadsheet module.
It is very simple to open excel file and use it.
But now only one excel file is being used (with multiple sheets), and I would like the file being used to be opened always on startup.
If I add the path and filename to command line arguments, noting happens...
Using devexpress components is very different then vanilla code for me, I am a complete beginner here, so I have no idea how to continue - can someone, please point me in the right direction?
I have made a procedure, to open the file dialog and load the file - I don't know how to "pass" it to devexpress, so the file actually loads to workbook.
Private Sub OpenXls()
Dim ofd As OpenFileDialog = New OpenFileDialog
ofd.DefaultExt = "xls"
ofd.FileName = "FILE"
ofd.InitialDirectory = "C:\ref_files"
ofd.Title = "Select file"
End Sub
As you have pointed out - using the dialog is not the right way.
After some googling I have find out that this should be a better way:
Dim workbook As New Workbook
workbook.LoadDocument("C:\ref_files\file.xls", DocumentFormat.xls)
I do not get any error, but the file is also not shown...
Do I have to display the document manually after loading?
If you're using openfiledialogue to open file then you must use command to load the specific file at Form.Load event.
The backslash char in ofd.InitialDirectory = "C:\ref_files"escapes the letter R to carrige return.
Change this line to ofd.InitialDirectory = "C:\\ref_files" (add another backslash).

Change Web Image via Excel Macro

I am using Excel macros to drive image changes for a webpage. If I want an image to change on the page, I execute the macro, which grabs the desired image and replaces the file the webpage is using, and the webpage refreshes automatically.
It works perfectly in a local machine, but the intent is for remote users to pull up the webpage and see the new image as I control the macro.
Here is the excel macro:
Sub update_image()
newName = "C:\Cases\Nominal\new_image_to_show.png"
oldName = "C:\Cases\Images\updated_image.png"
FileCopy newName, oldName
End Sub
When I replace the file locations with the web locations, the macro stops working. The web space is an internal location within my organization, and two options I tried were:
newName = "https:://location_of_content\Cases\Nominal\new_image_to_show.png"
oldName = "https:://location_of_content\Cases\Images\updated_image.png"
and
newName = "file://///location_of_content\Cases\Nominal\new_image_to_show.png"
oldName = "file://///location_of_content\Cases\Images\updated_image.png"
I also tried relative path nomenclature,
newName = ThisWorkbook.Path & "\Cases\Nominal\new_image_to_show.png"
but in both cases I get
Run Time Error '52'
Any ideas on how I can rename the paths? Or alternatives to Excel Macros?

Adding a macro file to an XLSX/XLSM file using Packaging

I'm using System.IO.Packaging to build simple Excel files. One of our customers would like to have an autorun macro that updates data and recalcs the sheet.
Pulling apart existing sheets I can see that all you need to do is add the vbaProject.bin file and change a few types in the _rels. So I made the macro in one file, extracted the vbaProject.bin, copied it into another file, and presto, there's the macro.
I know how to add package parts when they are in XML format, like the sheets or the workbook itself, but I've never added a binary file and I can't figure it out. Has anyone done this before?
Ok I got it. Following TnTinMn's suggestion:
Open a new workbook and type in your macro. Change the extension to
zip, open it, open the xl folder and copy out the vbaProject.bin
to somewhere easy to find.
In your .Net code, make a new Part and add it to the Package as
'xl/vbaProject.bin'. Copy over byte-for-byte from the
vbaProject.bin you extracted above. It will be compressed as you
add the bytes.
Then you have to add a relationship to the workbook that points to
your new file. You can find those relationships in
xl/_rels/workbook.xml.rels.
You also have to add a content type entry at the root of the
document, which goes into the [Content Types].xls. This happens automatically when you use the ContentType parameter of CreatePart
And finally, change the extension to .xlsm or .xltm
I'm extracting the following from many places in my code, so this is pseudo...
'the package...
Dim xlPackage As Package = Package.Open(WBStream, FileMode.Create)
'start with the workbook, we need the object before we physically insert it
Dim xlPartUri As URI = PackUriHelper.CreatePartUri(New Uri(GetAbsoluteTargetUri("/", "xl/workbook.xml"), UriKind.Relative)) 'the URI is relative to the outermost part of the package, /
Dim xlPart As PackagePart = xlPackage.CreatePart(xlPartUri, "application/vnd.ms-excel.sheet.macroEnabled.main+xml", CompressionOption.Normal)
'add an entry in the root _rels folder pointing to the workbook
xlPackage.CreateRelationship(xlPartUri, TargetMode.Internal, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument", "xlWorkbook") 'it turns out the ID can be anything unique
'now that we have the WB part, we can make our macro relative to it
Dim xlMacroUri As URI = PackUriHelper.CreatePartUri(New Uri(GetAbsoluteTargetUri("/xl/workbook.xml", "vbaProject.bin"), UriKind.Relative))
Dim xlMacroPart as PackagePart = xlPackage.CreatePart(xlPartUri, "application/vnd.ms-office.vbaProject", CompressionOption.Normal)
'time we link the vba to the workbook
xlParentPart.CreateRelationship(xlPartUri, TargetMode.Internal, "http://schemas.microsoft.com/office/2006/relationships/vbaProject", "rIdMacro") 'the ID on the macro can be anything as well
'copy over the data from the macro file
Using MacroStream As New FileStream("C:\yourdirectory\vbaProject.bin", FileMode.Open, FileAccess.Read)
MacroStream.CopyTo(xlMacroPart.GetStream())
End Using
'
'now write data into the main workbook any way you like, likely using new Parts to add Sheets

Open an Excel file in VBA without loading add ins?

I have some code that opens a file, copy/pastes some cells into a merged sheet, closes the file; then loops for all the files in a folder. Something like this:
Set SourceFile = Workbooks.Open(FilePath & FileName)
Set Ltab = SourceFile.Worksheets("Sheet1")
Ltab.Cells.Copy
NewTab.Cells.PasteSpecial xlPasteValuess
SourceFile.Close
Is there a line I can add that will stop Excel from loading add ins every time a file is opened? There are a lot of files and loading the add ins adds a good 5-10 seconds every time.
This didn't really answer my question, as I need a way to do it in VBA.
Thanks
So if you dont wana to disable all addins without naming them, and Installed = false is correct aproach try to iterate them with for each
Sub runWithoutAddins()
Dim var As AddIn
For Each var In AddIns
var.Installed = False
Next var
End Sub
I dont need to know their name, but this will loop every object in AddIn collection and set their atribute Installed to false. (which if im understanding it well, will disable them)

Release a file from excel generated by VBA to allow for moving of file

I am using some code in my excel document to open images, rotate them as appropriate and then save them to a temp folder (see How do I rotate a saved image with VBA?).
I am now trying to rename these generated images within the same folder using Name... as..., however this throws up an error, saying that the image is still in use by Excel ("File/Path access error" in VBA - it tells me its in use by excel when renaming it in an explorer window though)
Is there any way to "throw this out" of Excel using VBA before this stage? I did try Set p = Nothing (with p coming from Set p = .Pictures.Insert(Filepath)) but this still gives an error. The sheet that the new image is created from is deleted after it is saved to the temp folder so it does not exist on the sheet any more either. Once I fully close excel, I can rename the file again.
The "solution" I ended up with was to copy folder C:\Temp\a\ to C:\Temp\b\ and make the changes from there before copying to \\my\actual\location
This works OK as a decent workaround for this instance, but by no means a 100% complete answer to the question
YOUR CODE HERE.....
CLOSE
'by add "close" at the ending of your line before conducting the next action