Closedxml - get the link to an already open Excel workbook - c#

I have a project VSTO EXCEL. I would like to work with ClosedXML library, but can`t get the link on the open ActiveSheet. My code:
private void ThisWorkbook_Startup(object sender, System.EventArgs e)
{
var workbook = **?**;
var ws = workbook.Worksheet(1);
var rngHeaders = ws.Range("B3:F3");
rngHeaders.Style.Fill.BackgroundColor = XLColor.LightSalmon;
}
This example does`t work:
var workbook = ThisApplication.ThisWorkbook;
I know there is this way:
using (var workbook = new XLWorkbook())
{
var worksheet = workbook.Worksheets.Add("Sample Sheet");
worksheet.Cell("A1").Value = "Hello World!";
workbook.SaveAs("HelloWorld.xlsx");
}
But I have to work with already opened Workbook.

To open an Excel file with ClosedXML, you have to open a saved file (by filename) or a filestream. You can't open a workbook which is already opened in Excel or another application.

Related

Copying sheet to another Excel workbook using C# and OpenXML

Sheet 2 contains the lists which are created previously, and sheet 1 contains the links to sheet 2, so when I generate sheet 1, I want sheet 2 to be copied to the workbook.
static void CopySheet(string filename, string sheetName, string clonedSheetName) {
//Add new sheet to main workbook part
Sheets sheets = workbookPart.Workbook.GetFirstChild<Sheets>();
Sheet copiedSheet = new Sheet();
copiedSheet.Name = clonedSheetName;
copiedSheet.Id = workbookPart.GetIdOfPart(clonedSheet);
copiedSheet.SheetId = (uint)sheets.ChildElements.Count + 1;
sheets.Append(copiedSheet);
//Save Changes
workbookPart.Workbook.Save();
}
Try
using (ExcelPackage ExcelFile = new ExcelPackage(new System.IO.FileInfo(#"C:\temp\MyExcelFile.xlsx")))
{
ExcelFile.Workbook.Worksheets.Copy("SheetToCopyName", "SheetToCopyToName");
}
This is done with EPPlus which uses OpenXML library. If you're using another library let me know.

Convert XLSX to PDF on one page by Spire.Pdf (c#)

I have one page XLSX work sheet (invoice). I need to convert it to one page PDF document. For it I am using Spire library. But it covert my document to two pages.
Code:
using (ExcelPackage xlPackageRef = new ExcelPackage(totalXlsFile))
{
using (ExcelPackage xlPackage = new ExcelPackage(workXlsFile))
{
ExcelWorkbook wb = xlPackage.Workbook;
ExcelWorkbook wbRef = xlPackageRef.Workbook;
var sheetName = invoice.XlsSeznamFakturNazevListu;
OfficeOpenXml.ExcelWorksheet wsRef = wbRef.Worksheets[sheetName];
if (wsRef != null)
{
// create xls work file
wb.Worksheets.Add("faktura", wsRef);
xlPackage.Save();
// load Excel file
Workbook workbook = new Workbook();
workbook.LoadFromFile(workXlsFilePath);
// pdf file path
FileInfo pdfInvoiceFile = new FileInfo(pdfInvoiceTargetFolder + #"/" + pdfInvoiceFileName);
if (pdfInvoiceFile.Exists)
pdfInvoiceFile.Delete();
// create pdf file
workbook.SaveToFile(pdfInvoiceFile.FullName, Spire.Xls.FileFormat.PDF);
}
}
}
First, I suppose you were using Spire.XLS rather than Spire.PDF.
Second, you need to do some page setup before converting. Try below code:
Worksheet worksheet = workbook.Worksheets[index];
PageSetup setup = worksheet.PageSetup;
setup.FitToPagesWide = 1;
setup.FitToPagesTall = 1;

Copy specific worksheets to new Excel file

I have an Excel file.
I need to open it, select specific sheets from it, and convert those sheets to a PDF format. I am able to convert the whole excel file, I just don't know how to convert only the specific sheets.
My idea is to copy specific sheets from an existing file to a new temporary file, and convert that whole new temporary file to PDF.
Maybe there's an easier way?
My code so far is =>
using Word = Microsoft.Office.Interop.Word;
using Excel = Microsoft.Office.Interop.Excel;
public static void ExportExcel(string infile, string outfile, int[] worksheets)
{
Excel.Application excelApp = null;
Excel.Application newExcelApp = null;
try
{
excelApp = new Excel.Application();
excelApp.Workbooks.Open(infile);
//((Microsoft.Office.Interop.Excel._Worksheet)excelApp.ActiveSheet).PageSetup.Orientation = Microsoft.Office.Interop.Excel.XlPageOrientation.xlLandscape;
excelApp.ActiveWorkbook.ExportAsFixedFormat(Excel.XlFixedFormatType.xlTypePDF, outfile);
}
finally
{
if (excelApp != null)
{
excelApp.DisplayAlerts = false;
excelApp.SaveWorkspace();
excelApp.Quit();
}
}
}
Maybe the ExportAsFixedFormat method can be set to consider only specific pages (sheets) while converting?
If not, how do I copy the sheets from one file to another?
Thanks!
You might be able to just print the sheets you want from the original file. I fired up the Macro Recorder, selected a couple of sheets, and Saved As to PDF. Here's the code:
Sheets(Array("Sheet1", "Sheet2")).Select
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
"C:\Users\doug\Documents\Book1.pdf", Quality:=xlQualityStandard, _
IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=True
When I changed the selected sheets and ran again it worked as expected.
What's strange is that in the actual Save As dialog, you can go to Options and check "Selected Sheets." That's not available as a parameter to ExportAsFixedFormat, but it was automatically selected in the dialog, and maybe is the default also when called.
You could simply copy the file to the new destination, open the destination, remove the unwanted sheets and export. This is an example (tested) of my idea.
// infile is the excel file, outfile is the pdf to build, sheetToExport is the name of the sheet
public static void ExportExcel(string infile, string outfile, string sheetToExport)
{
Microsoft.Office.Interop.Excel.Application excelApp = new
Microsoft.Office.Interop.Excel.Application();
try
{
string tempFile = Path.ChangeExtension(outfile, "XLS");
File.Copy(infile, tempFile, true);
Microsoft.Office.Interop.Excel._Workbook excelWorkbook =
excelApp.Workbooks.Open(tempFile);
for(int x = excelApp.Sheets.Count; x > 0; x--)
{
_Worksheet sheet = (_Worksheet)excelApp.Sheets[x];
if(sheet != null && sheet.Name != sheetToExport)
sheet.Delete();
}
excelApp.ActiveWorkbook.ExportAsFixedFormat(XlFixedFormatType.xlTypePDF, outfile);
}
finally
{
if (excelApp != null)
{
excelApp.DisplayAlerts = false;
excelApp.SaveWorkspace();
excelApp.Quit();
}
}
}

How to merge two Excel workbook into one workbook in C#?

Let us consider that I have two Excel files (Workbooks) in local. Each Excel workbook is having 3 worksheets.
Lets say WorkBook1 is having Sheet1, Sheet2, Sheet3
Workbook2 is having Sheet1, Sheet2, Sheet3.
So here I need to merge these two excel workbook into one and the new excel workbook that is let's say Workbook3 which will have total 6 worksheets (combination of workbook1 and workbook2).
I need the code that how to perform this operation in c# without using any third party tool. If the third party tool is free version then its fine.
An easier solution is to copy the worksheets themselves, and not their cells.
This method takes any number of excel file paths and copy them into a new file:
private static void MergeWorkbooks(string destinationFilePath, params string[] sourceFilePaths)
{
var app = new Application();
app.DisplayAlerts = false; // No prompt when overriding
// Create a new workbook (index=1) and open source workbooks (index=2,3,...)
Workbook destinationWb = app.Workbooks.Add();
foreach (var sourceFilePath in sourceFilePaths)
{
app.Workbooks.Add(sourceFilePath);
}
// Copy all worksheets
Worksheet after = destinationWb.Worksheets[1];
for (int wbIndex = app.Workbooks.Count; wbIndex >= 2; wbIndex--)
{
Workbook wb = app.Workbooks[wbIndex];
for (int wsIndex = wb.Worksheets.Count; wsIndex >= 1; wsIndex--)
{
Worksheet ws = wb.Worksheets[wsIndex];
ws.Copy(After: after);
}
}
// Close source documents before saving destination. Otherwise, save will fail
for (int wbIndex = 2; wbIndex <= app.Workbooks.Count; wbIndex++)
{
Workbook wb = app.Workbooks[wbIndex];
wb.Close();
}
// Delete default worksheet
after.Delete();
// Save new workbook
destinationWb.SaveAs(destinationFilePath);
destinationWb.Close();
app.Quit();
}
Edit: notice that you might want to Move method instead of Copy in case you have dependencies between the sheets, e.g. pivot table, charts, formulas, etc. Otherwise the data source will disconnect and any changes in one sheet won't effect the other.
Here's a working sample that joins two books into a new one, hope it will give you an idea:
using System;
using Excel = Microsoft.Office.Interop.Excel;
using System.Reflection;
namespace MergeWorkBooks
{
class Program
{
static void Main(string[] args)
{
Excel.Application app = new Excel.Application();
app.Visible = true;
app.Workbooks.Add("");
app.Workbooks.Add(#"c:\MyWork\WorkBook1.xls");
app.Workbooks.Add(#"c:\MyWork\WorkBook2.xls");
for (int i = 2; i <= app.Workbooks.Count; i++)
{
int count = app.Workbooks[i].Worksheets.Count;
app.Workbooks[i].Activate();
for (int j=1; j <= count; j++)
{
Excel._Worksheet ws = (Excel._Worksheet)app.Workbooks[i].Worksheets[j];
ws.Select(Type.Missing);
ws.Cells.Select();
Excel.Range sel = (Excel.Range)app.Selection;
sel.Copy(Type.Missing);
Excel._Worksheet sheet = (Excel._Worksheet)app.Workbooks[1].Worksheets.Add(
Type.Missing, Type.Missing, Type.Missing, Type.Missing
);
sheet.Paste(Type.Missing, Type.Missing);
}
}
}
}
}
You're looking for Office Autmation libraries in C#.
Here is a sample code to help you get started.
System.Data.Odbc.OdbcDataAdapter Odbcda;
//CSV File
strConnString = "Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq=" + SourceLocation + ";Extensions=asc,csv,tab,txt;Persist Security Info=False";
sqlSelect = "select * from [" + filename + "]";
System.Data.Odbc.OdbcConnection conn = new System.Data.Odbc.OdbcConnection(strConnString.Trim());
conn.Open();
Odbcda = new System.Data.Odbc.OdbcDataAdapter(sqlSelect, conn);
Odbcda.Fill(ds, DataTable);
conn.Close();
This would read the contents of an excel file into a dataset.
Create multiple datasets like this and then do a merge.
Code taken directly from here.

opening .xlsx in office 2003

I have created a .xlsx using openxml.
I am not able to open this file in office 2003.. I have also tried using compatibility pack but still the file does not open. What can be done if i need to generate .xlsx that can be opened in office 2003 as well.
Code i am using to generate .xlsx is :
public static void HelloWorldXlsx(string docName)
{
SpreadsheetDocument package = SpreadsheetDocument.Create(docName, SpreadsheetDocumentType.Workbook);
package.AddWorkbookPart();
package.WorkbookPart.Workbook = new Workbook();
WorksheetPart wspart = package.WorkbookPart.AddNewPart<WorksheetPart>();
Cell cell = new Cell();
cell.DataType = CellValues.InlineString;
cell.InlineString = new InlineString(new DocumentFormat.OpenXml.Spreadsheet.Text("Hello World!"));
wspart.Worksheet = new Worksheet(new SheetData(new Row(cell)));
wspart.Worksheet.Save();
package.WorkbookPart.Workbook.AppendChild(new Sheets());
Sheet sheet = new Sheet();
sheet.Id = package.WorkbookPart.GetIdOfPart(wspart);
sheet.SheetId = 1;
sheet.Name = "Hello !";
package.WorkbookPart.Workbook.GetFirstChild<Sheets>().AppendChild<Sheet>(sheet);
package.WorkbookPart.Workbook.Save();
package.Close();
}
Thanks for suggestion. I got the answer to my question .. I had not set cellReference property of Cell in my code.

Categories