Save Entire Workbook as PDF Excel 2010 (C#) - c#

Is there anyway to save you entire workbook as a pdf in excel. I found this, http://msdn.microsoft.com/en-us/library/bb407651(v=office.12).aspx, but it does not exactly tell you if it saves the entire workbook as a pdf or just the active sheet. If there is no way to save the entire workbook to pdf, would printing the entire workbook be the best option, or even possible in C#? Below is what I have thus far I just need it to save as pdf so I can send in an email. Thanks for the help.
using Excel = Microsoft.Office.Interop.Excel; //Excel Reference
//Gets Excel and gets Activeworkbook and worksheet
Excel.Application oXL;
Excel.Workbook oWB;
Excel.Worksheet oSheet;
//Create New Instance in Excel
oXL = new Excel.Application();
oXL.Visible = true;
//Open Excel Workbook
oWB = oXL.Workbooks.Open("");
oWB = (Excel.Workbook)oXL.ActiveWorkbook;
oSheet = (Excel.Worksheet)oWB.ActiveSheet;
//Modify Excel Spreadsheet Based on Form
oSheet.Cells[6, 4] = maskedTextBox1.Text; //Change Value in Cell, Cell Location [y-axis, x-axis]
//Save Workbook As
oWB.SaveAs("");
//Save Workbook As PDF
//Close Workbook
oWB.Close("");
//Quit Excel
oXL.Quit();

In 2010 you can save the entire workbook in PDF by making each sheet an "Active" sheet.
Sounds strange but if you notice the print options when you do a pdf there is no option for workbook. To get around this open an excel file and fill in some data in 2-3 work sheets. Now hold your ctrl key and click on each other workbook, it will then become a "Group".
You will notice the [GROUP] name appear at the top of the excel file and now when you print the excel file it will print the entire workbook.
Try this out for yourself. In code, you just need to make each work sheet an active worksheet. I don't work much with the excel object model but it might be worth doing a macro for this and looking at the code.
I recorded a macro and here is the VBA:
Sheets(Array("Sheet1", "Sheet2", "Sheet3")).Select
Looks as though you just need to store each sheet in an array and then simply
Sheets(MyArray).Select
This will then make all sheets active and [grouped] and then you can run a print out to pdf. By recording the macro it also presented the options to print to pdf:
`ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
"C:\Users\MyAccount\Desktop\test.pdf", Quality:=xlQualityStandard, _
IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:= _
True`
In this case active sheet is your group of sheets that you have stored in an array.

Related

Excel Interop - Set filename before saving

Is it possible to set the excel filename before file saving?
I have following simple code:
using Excel = Microsoft.Office.Interop.Excel;
Excel.Application excel = new Excel.Application();
excel.Visible = true;
Excel.Workbook workbook = excel.Workbooks.Add(Excel.XlSheetType.xlWorksheet);
Excel.Worksheet sheet = workbook.Sheets[1];
sheet.Cells[1, 1] = "Hello World!";
Is it possible to predefine this name before saving?
Thanks.
There is no explicit, foolproof way to do this prior to saving, unfortunately. The closest you could come is to use a template. If you have a template called FOO.xltx, you could create your workbook like this:
Application.Workbooks.Add "X:\path\to\FOO.xltx"
The only quirk is that the name for the new documents will be appended with an incrementing number (FOO1 the first time, then FOO2,FOO3, etc.).
To create a template, just create a new document, and when you save it, select Excel Template (*.xltx) from the Save as type dropdown.
You have to use saveas to save the file with the filename you want. Then when the user clicks save it will just update the file that was previously created. Unfortunately there is no other way. Here is the code:
workbook.SaveAs(Filename: FILENAMEHERE);
Here is the MSDN doc for it: https://msdn.microsoft.com/en-us/library/microsoft.office.tools.excel.workbook.saveas.aspx

Open an Excel workbook inside a blank excel workbook using Marshal.GetActiveObject

I have created a number of unit tests. At the beginning of each test I open a blank excel workbook on the TestInitialize however for this particular test I need to open another excel workbook. I want to open it inside the blank workbook opened on the TestInitialize . I tried doing the following however it opens them as 2 separate workbooks.
Any ideas why this is happening?
My code is as follows
using xl = Microsoft.Office.Interop.Excel;
private static string columnChartTemp = #"Testing\V8\TestMaster\V8.6\Testing\V8.6.0.11 Testing\columnChart.xlsx";
var excel = (xl.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
var myWorkbook = excel.Workbooks.Open(columnChartTemp);
excel.Visible = true;
A workbook is a file containing one or more worksheets (tabs.) You can't open a workbook inside of another workbook.
It sounds like you want to take a worksheet that's in a workbook and add it to another workbook. You can do that. Open both workbooks and copy the sheet from one to the other.

Pass parameters to VSTO-enabled Excel Spreadsheet on server

I created an Excel 2010 Workbook project with to customize some ribbon extensions. It uses a webservice to read in data to pre-populate the form. My question is, how can I pass in some parameters, for example a record ID, to the workbook when it is requested from the server?
I think my scenario is similar to this question, which was never answered: Pass Data into a VSTO Excel Workbook?
There is a way of passing data to a workbook which personally I don't really like, but maybe it can suit you. Basically, you set values for specific cells in the workbook, and then process those values in Excel's event handler:
Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook wb = excel.Workbooks.Open(filepath);
var sheet = (Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets[1];
var range = sheet.Range["A1"];
range.Value2 = "some value";

Get the current Workbook Object in C#

I've been writing an application in C# which creates Custom Document properties in an Excel spreadsheet, I have a function for this which takes in a Workbook Object...
However, actually getting the current Workbook object is proving to be quite annoying, I am using ExcelDNA to add functionality, however, I can't seem to pass my function a valid Workbook COM object.
If you need to find the activeworkbook with C#, if you are using Office Interop, you can try this kind of code:
(Workbook)Globals.ThisAddIn.Application.ActiveWorkbook;
[Source]
This is the way I am currently doing it it seems to work really well
using Excel = Microsoft.Office.Interop.Excel;
Then you get active workbook
//Gets Excel and gets Activeworkbook and worksheet
Excel.Application oXL;
Excel.Workbook oWB;
Excel.Worksheet oSheet;
oXL = (Excel.Application)Marshal.GetActiveObject("Excel.Application");
oXL.Visible = true;
oWB = (Excel.Workbook)oXL.ActiveWorkbook;
docProps = oWB.CustomDocumentProperties
Then I would try what you have and see how it works
Hope this helps
As #Govert explained above in his comment:
using Excel = Microsoft.Office.Interop.Excel;
using ExcelDna.Integration;
// Get the correct application instance
Excel.Application xlapp = (Excel.Application)ExcelDnaUtil.Application;
// Get active workbook
Excel.Workbook wbook = xlapp.ActiveWorkbook;
GetActiveObject() looks in the Running Object Table (ROT) and gives you the last Excel instance opened which may not corresponding with top Z order excel window.
Loop through the Z order and find the matching workbook.
See this link: -
https://social.msdn.microsoft.com/Forums/office/en-US/060000d8-a899-49bf-a965-0576dee958d4/how-to-get-active-application?forum=exceldev

Enable Excel Macro in codes?

I am working an existing project which is base do Excel class to copy values from one worksheet A to another one B. There are some formulas and Addin functions in ws A cells. The copy codes are used to copy only values out to ws B as a result. Here is a block of simplified codes:
using Excel = Microsoft.Office.Interop.Excel;
....
object missing = System.Type.Missing;
Excel.Application app = new Excel.Application();
// Creating Excel application with source workbook in memory
Excel.Workbook workbook = app.Workbooks.Open("SourceA.xls",
Excel.XlUpdateLinks.xlUpdateLinksNever,....);
...
app.Calculate() // Forcing to recalculate value in cells.
...
//create destination workbook
Excel.Workbook destWb = app.Workbooks.Add(Excel.XlWBATemplate.xlWBATWorksheet);
Excel.WorkSheet destSheet = (Excel.Worksheet)destWb.Worksheets[1];
Excel.Range destRange = (Excel.Range)destSheet.Cells[1, 1];
//rename sheet 1
destSheet.Name = "wsB Report";
//Set Source Data Range from
Excel.WorkSheet sourceWA = (Excel.Worksheet)workbook.Worksheets["wsA"];
//Get the predefined named range "DataRange" from source wsA
Excel.Range sourceRange = sourceWA.get_Range("DataRange", missing);
//copy data
sourceRange.Copy(missing);
//paste values and number formats
destRange.PasteSpecial(Excel.XlPasteType.xlPasteValuesAndNumberFormats,
Excel.XlPasteSpecialOperation.xlPasteSpecialOperationNone, missing, missing);
//paste formats
destRange.PasteSpecial(Excel.XlPasteType.xlPasteFormats,
Excel.XlPasteSpecialOperation.xlPasteSpecialOperationNone, missing, missing);
//paste column widths
destRange.PasteSpecial(Excel.XlPasteType.xlPasteColumnWidths,
Excel.XlPasteSpecialOperation.xlPasteSpecialOperationNone, missing, missing);
....
destWb.SaveAs("destB.xls", missing, ....);
The problem I have is that the copies cells in destB.xls are all marked as "#NAME?". They should be values copied. I open the source excel file and I can see the data in the source range are updated with values. However, when I run my codes, the values seem not available.
I guess that the Excel application I created in my codes may not have Macro enabled. This may be reason values cannot be copied. For example, when I open the source excel file, I'll see a prompt to enable or disable Macros. If I click on Enable button, the excel will take some time to display values in data cells.
If that is the reason, is there any way in codes to enable Macro so that all formulas in cells will be able to update values?
Another reason might be caused by OS or Windows security updates. Not sure if any Windows security settings may affect Excel macros. If this is the case, should I change Windows security level or any way to force Macros enabled in my project?
By the way, my project runs in Windows XP and Windows 2008 Server, with Office Excel 2003 installed. The project was done in VS 2008.
I went further into my codes and I found that by making Excel app visible, I'd able to see what actually happened. As Ben Voigt's suggestion, the security settings for Macro can be done in Excel, but in codes, you can force to execute any VBA-like codes no matter what the setting is. Here are some codes to make Excel visible and see all the prompt dialogs:
Excel.Application app = new Excel.Application();
Excel.Workbook workbook = app.Workbooks.Open("SourceA.xls", ...);
app.Visible = true; //set to 'true' when debbugging, Exec is visible
app.DisplayAlerts = true; //enable all the prompt alerts for debug.
...
For example, I rebuild links in my C# codes, set values in cells and refresh or calculate values(simulate F9). By making Excel visible, I saw what was going on and found bugs in my codes which did not do what I want.

Categories