I would like to export a specific worksheet of my excel file to PDF.
When I do wbk.ExportAsFixedFormat it work but it dosn't work when I do worksheet.ExportAsFixedFormat.
Someone can help me?
I have to "activate" the worksheet maybe ?
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Microsoft.Office.Interop.Excel;
namespace XLConvert
{
class Program
{
static void Main(string[] args)
{
Application app = new Application();
Workbook wkb = app.Workbooks.Open(#"C:\Users\ALPIC\Desktop\XL\0000351608.xlsx");
var worksheet = wkb.Sheets["FRA"];
worksheet.ExportAsFixedFormat(XlFixedFormatType.xlTypePDF, #"C:\Users\ALPIC\Desktop\XL\0000351608.pdf");
wkb.Close(false, #"C:\Users\ALPIC\Desktop\XL\0000351608.xlsx");
Marshal.ReleaseComObject(wkb);
}
}
}
Thanks!
I found !
I tried this and it works :
static void Main(string[] args)
{
Application app = new Application();
Workbook wkb = app.Workbooks.Open(#"C:\Users\ALPIC\Desktop\XL\0000351608.xlsx");
((Worksheet)wkb.Sheets["FRA"]).ExportAsFixedFormat(XlFixedFormatType.xlTypePDF, #"C:\Users\ALPIC\Desktop\XL\0000351608.pdf");; //activates first sheet
wkb.Close(false, #"C:\Users\ALPIC\Desktop\XL\0000351608.xlsx");
Marshal.ReleaseComObject(app);
}
From the looks of it, var worksheet = wkb.Sheets["FRA"]; gets assigned as a worksheet collection, while you specifically assigned wkb as a workbook, which has that function.
Related
I have an SSIS package which is populating an existing excel (template) with data via a Data Flow Task. The issue I am having is that I am dynamically creating worksheets and want to add a Hyperlink from the main page to the appropriate worksheet in that workbook.
I add the =Hyperlink reference to the appropriate sheet in the data flow task and it carries through just fine but the link (despite the column type being 'General') is not actually showing as a Hyperlink until I actually click in the cell, then it looks good.
I thought I could use a C# script task to flip the column to 'Text' and then back to 'General' and maybe that would make it read properly but no luck. Any ideas how I can simulate a double click in each of the cells in my column?
Here is what I have so far, which works for converting the column to general and wrapping text in another column but I am at a loss as to how to make this formula display properly as a Hyperlink.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;
#endregion
namespace ST_2bdf93d5542441248076f053703d32c9
{
[Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
public void Main()
{
string inputFile = (string)Dts.Variables["RecommendationFileName"].Value;
Excel.Application ExcelApp = new Excel.Application();
Excel.Workbook ExcelWorkbook = ExcelApp.Workbooks.Open(inputFile);
ExcelApp.Visible = true;
Excel.Worksheet xlWorkSheetFocus = (Excel.Worksheet)ExcelWorkbook.Worksheets.get_Item(2);
xlWorkSheetFocus.Activate();
xlWorkSheetFocus.Select(Type.Missing);
Excel.Range usedRange = xlWorkSheetFocus.UsedRange;
xlWorkSheetFocus.Columns[5].NumberFormat = ""; //Make column 5 type General
xlWorkSheetFocus.Columns[4].WrapText = true; //Wrap text in column 4
ExcelWorkbook.Save();
GC.Collect();
GC.WaitForPendingFinalizers();
ExcelWorkbook.Close(Type.Missing, Type.Missing, Type.Missing);
Marshal.FinalReleaseComObject(ExcelWorkbook);
ExcelApp.Quit();
Marshal.FinalReleaseComObject(ExcelApp);
}
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
}
}
Well looks like I found a workable solution using text to columns, picking a delimiter "#" which doesn't exists, and writing the results to the same column/cell. Guessing there might be a better way but it gets me a clickable link.
xlWorkSheetFocus.get_Range("E6", ("E6" +
xlWorkSheetFocus.UsedRange.Rows.Count)).TextToColumns(Type.Missing,
Microsoft.Office.Interop.Excel.XlTextParsingType.xlDelimited,
Microsoft.Office.Interop.Excel.XlTextQualifier.xlTextQualifierNone, true,
Type.Missing, Type.Missing, false, true, Type.Missing,
"#", Type.Missing, Type.Missing, Type.Missing, Type.Missing);
I am using oledb to read .xls files in my application. It is working fine but real issue comes when my excel contains merged cells in rows or in column.
This is the data in excel
This is how it show on screen using webgrid
The VERY first thing that I would say is STAY VERY FAR AWAY FROM MERGED CELLS IN EXCEL!! That is the work of the DEVIL. Ok, if you still want to do this, consider the following options (you don't have many options) . . .
using Spire.Xls;
namespace Detect_Merged_Cells
{
class Program
{
static void Main(string[] args)
{
Workbook workbook = new Workbook();
workbook.LoadFromFile("Sample.xlsx");
Worksheet sheet = workbook.Worksheets[0];
CellRange[] range = sheet.MergedCells;
foreach (CellRange cell in range)
{
cell.UnMerge();
}
workbook.SaveToFile("Output.xlsx",ExcelVersion.Version2010);
}
}
}
OR
Excel.Range firstCell = excelWorksheet.get_Range("A1", Type.Missing);
Excel.Range lastCell = excelWorksheet.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell, Type.Missing);
object[,] cellValues;
object[,] cellFormulas;
Excel.Range worksheetCells = excelWorksheet.get_Range(firstCell, lastCell);
cellValues = worksheetCells.Value2 as object[,];
cellFormulas = worksheetCells.Formula as object[,];
I wrote program to convert .xls to .xlsx, the program changes the extension but epplus functions are not working the converted file. below is the code to convert .xls to .xlsx and color the cells of .xlsx file, the program is running without any errors or exception, but the excel is not getting edited with the colors after running the program
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Drawing;
using OfficeOpenXml;
using OfficeOpenXml.Style;
namespace Project42
{
class Class1
{
static void Main(string[] args)
{
Console.WriteLine("File Extension Conversion From .xls to .xlsx");
try
{
string filePath = #"C:\Users\mvmurthy\Desktop\abc.xls";
if (filePath.EndsWith(".xls"))
{
File.Move(filePath, Path.ChangeExtension(filePath, ".xlsx"));
Console.WriteLine("File Extension Updated To .xlsx");
}
FileInfo newFile = new FileInfo(#"C:\Users\mvmurthy\Downloads\abc.xlsx");
ExcelPackage pck = new ExcelPackage(newFile);
var ws = pck.Workbook.Worksheets["Contents"];
ws.Cells["K:K"].Style.Fill.PatternType = ExcelFillStyle.Solid;
ws.Cells["K:K"].Style.Fill.BackgroundColor.SetColor(Color.Yellow);
ws.Cells["M:M"].Style.Fill.PatternType = ExcelFillStyle.Solid;
ws.Cells["M:M"].Style.Fill.BackgroundColor.SetColor(Color.Yellow);
ws.Cells["O:O"].Style.Fill.PatternType = ExcelFillStyle.Solid;
ws.Cells["O:O"].Style.Fill.BackgroundColor.SetColor(Color.Yellow);
pck.Save();
}
catch (Exception)
{
Console.WriteLine("File Extension Cannot Be Changed...Try again...");
}
}
}
}
You cant just change the file extension, you may be able to use office automation to resave as .xlsx. if the data is simple enough you can just first read the data using office automation or other library that supports .xls, then write the .xlsx using epplus.. which will then work on the .xlsx format.
How would you rename a "Using Directive" Using C#?
Because some times You copy a class from somewhere (Example below)
//Other Code
Excel.ApplicationClass excel;
Excel.Workbooks workbooks;
Excel.Workbook workbook;
Excel.Worksheet worksheet;
Excel.Sheets worksheets;
//Other Code
and instead of renaming everything to
//Other Code
Microsoft.Office.Interop.Excel.ApplicationClass excel;
Microsoft.Office.Interop.Excel.Workbooks workbooks;
Microsoft.Office.Interop.Excel.Workbook workbook;
Microsoft.Office.Interop.Excel.Worksheet worksheet;
Microsoft.Office.Interop.Excel.Sheets worksheets;
//Other Code
So having something like
Using Microsoft.Office.Interop.Excel.ApplicationClass as 'Excel'
You can create an alias like this:
// for whole namespace
using Excel = Microsoft.Office.Interop.Excel;
// use like this
Excel.ApplicationClass excel = /* ... */;
// or for single type
using ExcelApp = Microsoft.Office.Interop.Excel.ApplicationClass;
// use like this
ExcelApp excel = /* ... */;
I think you're just looking for:
using Excel = Microsoft.Office.Interop.Excel;
(I don't think you wanted ApplicationClass here. That would be an alias for the type rather than the Microsoft.Office.Interop.Excel namespace. It's not really clear from your question though.)
This is called a using-alias-directive. From section 9.4.1 of the C# 4 spec:
A using-alias-directive introduces an identifier that serves as an alias for a namespace or type within the immediately enclosing compilation unit or namespace body.
So after that using directive, it would be valid to have:
Excel.ApplicationClass excel = new Excel.ApplicationClass();
... which is what I think you wanted?
What about:
using Excel = Microsoft.Office.Interop.Excel;
As the msdn documentation says http://msdn.microsoft.com/en-us/library/sf0df423%28v=vs.71%29.aspx
using [alias = ]class_or_namespace;
So in your case:
using Excel = Microsoft.Office.Interop.Excel;
I am trying to add a new worksheet to an Excel workbook and make this the last worksheet in the book in C# Excel Interop.
It seems really simple, and I thought the below code would do it:
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
var excel = new Excel.Application();
var workbook = excel.Workbooks.Open(#"C:\test\Test.xlsx");
workbook.Sheets.Add(After: workbook.Sheets.Count);
workbook.Save();
workbook.Close();
Marshal.ReleaseComObject(excel);
}
}
}
No such luck. I get this helpful error:
COMException was unhandled - Exception from HRESULT: 0x800A03EC
I found this page on Microsoft.com which suggested I try and add the sheet first and then move it so I tried that as shown below. I know that this webpage targets Excel 95 but the VBA is still there to use so I was hoping it would still work:
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
var excel = new Excel.Application();
var workbook = excel.Workbooks.Open(#"C:\test\Test.xlsx");
workbook.Sheets.Add();
workbook.Sheets.Move(After: workbook.Sheets.Count);
workbook.Save();
workbook.Close();
Marshal.ReleaseComObject(excel);
}
}
}
I get the same error as above. I have also tried passing the name of my last worksheet as a string as the After parameter in both the Add and Move methods, no joy!
That is what I have tried, so my question is how do I add a worksheet to an Excel workbook and make this the last sheet in the workbook using C# Excel Interop?
Thanks
Looking at the documentation here http://msdn.microsoft.com/en-us/library/microsoft.office.tools.excel.worksheet.move(v=vs.80).aspx, it indicates that the 'after' object isn't a numerical position; it's the object representing the sheet you want to position your sheet after. The code should probably be something like (untested):
workbook.Sheets.Add(After: workbook.Sheets[workbook.Sheets.Count]);
This should do the job:
wSheet.Move(Missing.Value, workbook.Sheets[workbook.Sheets.Count]);
This is the only way that works for me:
xlWorkSheet = (Microsoft.Office.Interop.Excel.Worksheet)xlWorkBook.Worksheets.Add
(System.Reflection.Missing.Value,
xlWorkBook.Worksheets[xlWorkBook.Worksheets.Count],
System.Reflection.Missing.Value,
System.Reflection.Missing.Value);
it works for me
WorkBook.Worksheets.Add(
System.Reflection.Missing.Value,
WorkBook.Worksheets[WorkBook.Worksheets.Count],
1,
System.Reflection.Missing.Value);