var wb = new XLWorkbook();
var ws = wb.AddWorksheet("Sheet1");
ws.FirstCell().SetValue("A")
.CellBelow().SetValue(1)
.CellBelow().SetValue(2);
ws.RangeUsed().SetAutoFilter().Column(1).EqualTo(1);
ws.AutoFilter.Column(1).Clear(); // Clear the filter for a column
ws.AutoFilter.Clear(); // Remove the autofilter from the worksheet
New Post: Disable AutoFilter in Table
Commented Unassigned: Index of RowLabel and ColumnLabel in PivotTable [9326]
Line 2222
Creation of RowLabels
```
var f = new Field {Index = pt.Fields.IndexOf(xlpf)};
```
Line 2240
```
var f = new Field {Index = pt.Fields.IndexOf(xlpf)};
```
The index of RowLabels and ColumnLabels is not correct because it is based on the order of Fields Collection
Is it correct changing the code in this way?
```
var f = new Field {Index = pt.RowLabels.IndexOf(pt.RowLabels.FirstOrDefault(p => p.SourceName == xlpf.SourceName))};
```
```
var f = new Field { Index = pt.ColumnLabels.IndexOf(pt.ColumnLabels.FirstOrDefault(p => p.SourceName == xlpf.SourceName)) };
```
Comments: ``` var dt = new System.Data.DataTable(); dt.Columns.Add("col1", typeof(string)); dt.Columns.Add("col2", typeof(string)); dt.Columns.Add("col3", typeof(double)); var col1 = new string[] { "col1_val1", "col1_val2", "col1_val3" }; var col2 = new string[] { "col2_val1", "col2_val2", "col2_val3" }; var rnd = new Random(); for (int i = 0; i < 10; i++) { var row = dt.NewRow(); row["col1"] = col1[rnd.Next(0, 3)]; row["col2"] = col2[rnd.Next(0, 3)]; row["col3"] = rnd.NextDouble() * rnd.Next(10, 100); dt.Rows.Add(row); } var workbook = new XLWorkbook(); var sheet = workbook.Worksheets.Add("Sheet1"); var table = sheet.Cell(1, 1).InsertTable(dt, "Table1", true); var range = table.DataRange; var header = sheet.Range(1, 1, 1, dt.Columns.Count); var dataRange = sheet.Range(header.FirstCell(), range.LastCell()); var ptSheet = workbook.Worksheets.Add("Sheet2"); var pt = ptSheet.PivotTables.AddNew("TablePivot", ptSheet.Cell(1, 1), dataRange); // COL2 then COL1 pt.RowLabels.Add("col2"); pt.RowLabels.Add("col1"); pt.Values.Add("col3"); workbook.SaveAs("workbook.xlsx"); ``` In the output excel file, the rowfields order in the pivot table is col1 first and then col2
New Post: Insert Recordset to Existing Worksheet
With that said, I'm moving away from Interop.Excel for many reasons but it seems I'm having problems converting some of my scripts to use ClosedXML.
My issue is not having my query results in the spreadsheet. I pass the results into the script in a variable but don't get the expected result. Before I could simply do the following.
objWorkBook = objExcel.Workbooks.Open(strReportFileLocation & strReportFileName)
myRecordset = Dts.Variables("gvRecordSet").Value
objWorkSheet = objWorkBook.Worksheets("SomeCharges")
__objWorkSheet.Cells(3, 1).CopyFromRecordset(myRecordset)__
Now with ClosedXML I'm using the following code. I do not receive any errors but I have no data on my spreadsheet either. Public Sub Main()
Dim FilePath As String
Dim Filename As String
Dim Recordset As Object
Dim filespec As String
FilePath = Dts.Variables("gvReportFileLocation").Value.ToString
Filename = Dts.Variables("gvReportFileName").Value.ToString
Recordset = CType(Dts.Variables("gvRecordSet").Value, String)
filespec = (FilePath & Filename)
Dim Workbook As New XLWorkbook(filespec)
Dim Worksheet As IXLWorksheet
Worksheet = Workbook.Worksheet("SomeFees")
Dim CellForNewData As IXLCell
CellForNewData = Worksheet.Cell(3, 1)
CellForNewData.InsertData(Recordset)
Thanks in advance for any help.New Post: Insert Recordset to Existing Worksheet
Thanks
Source code checked in, #1571ed8f1d75c98f7e6f0c6e2047d73f5cfe0a95
Closed Unassigned: Index of RowLabel and ColumnLabel in PivotTable [9326]
Line 2222
Creation of RowLabels
```
var f = new Field {Index = pt.Fields.IndexOf(xlpf)};
```
Line 2240
```
var f = new Field {Index = pt.Fields.IndexOf(xlpf)};
```
The index of RowLabels and ColumnLabels is not correct because it is based on the order of Fields Collection
Is it correct changing the code in this way?
```
var f = new Field {Index = pt.RowLabels.IndexOf(pt.RowLabels.FirstOrDefault(p => p.SourceName == xlpf.SourceName))};
```
```
var f = new Field { Index = pt.ColumnLabels.IndexOf(pt.ColumnLabels.FirstOrDefault(p => p.SourceName == xlpf.SourceName)) };
```
Comments: Thanks. Pick up the latest source code.
Released: ClosedXML 0.71.2 (May 30, 2014)
Fixed an issue with pivot table field order.
Created Release: ClosedXML 0.71.2 (May 30, 2014)
Fixed an issue with pivot table field order.
Commented Unassigned: workbook.SaveAs hangs for ever [9263]
> workbook.SaveAs(outputPath);
the problem is , that when I open my website in 3 tabs, and click in each to generate my report, then when code comes to SaveAs all tabs are hanging for ever,
closedxml i saving for ever, i was waiting 30 minutes and nothing, all is on my local machine, what I can do ? How can I check anything ?
Comments: v0.71.2 saves the file in < 20s
Source code checked in, #6284cf3c3991c258e1616c798e5ca9b82b0cd130
New Post: Insert Recordset to Existing Worksheet
Imports System
Imports System.Data
Imports System.Math
Imports Microsoft.SqlServer.Dts.Runtime
Imports ClosedXML.Excel
Public Class ScriptMain
Public Sub Main()
Dim FilePath As String
Dim Filename As String
Dim filespec As String
Dim Recordset As Object
Recordset = "Row1 Column1, Row1 Column2" & vbCrLf & "Row2 Column1, Row2 Column2" 'CType(Dts.Variables("gvRecordSet").Value, String)
FilePath = "C:\Billing\" 'Dts.Variables("gvReportFileLocation").Value.ToString
Filename = "Test_Excel.xlsx" 'Dts.Variables("gvReportFileName").Value.ToString
filespec = (FilePath & Filename)
Dim Workbook As New XLWorkbook(filespec)
Dim Worksheet As IXLWorksheet
Worksheet = Workbook.Worksheet("sheet1")
Dim NumberOfLastRow As Integer
Dim CellForNewData As IXLCell
Try
NumberOfLastRow = Worksheet.LastRowUsed().RowNumber
CellForNewData = Worksheet.Cell(3, 1)
CellForNewData.InsertData(Recordset.ToString)
Catch ex As Exception
End Try
End Sub
End ClassNew Post: Insert Recordset to Existing Worksheet
New Post: Cell Merge Performance
All pandering aside, I could use some help with optimizing my code. I have a very large excel document with some complex formatting that I need programmatically generated. I have noticed some performance hits on merging ranges. I was hoping for some suggestions on this.
Here is some code that represents a small piece of what I am doing:
var timer = System.Diagnostics.Stopwatch.StartNew();
using (XLWorkbook wb = new XLWorkbook(XLEventTracking.Disabled))
{
using (var ws = wb.AddWorksheet("MergeCellsWorksheet"))
{
int total = 5000;
// Insert rows first
ws.Row(total).InsertRowsAbove(total);
// Get Ranges
var merge1 = ws.Ranges("ZZ1:ZZ1");
var merge2 = ws.Ranges("ZZ2:ZZ2");
var merge3 = ws.Ranges("ZZ3:ZZ3");
var merge4 = ws.Ranges("ZZ4:ZZ4");
// Insert some values
for (int i = 1; i <= total; i+=2)
{
ws.Cell(i, 1).Value = "Merge Cell 1";
ws.Cell(i, 3).Value = "Merge Cell 2";
ws.Cell(i, 4).Value = "Merge Cell 3";
ws.Cell((i+1), 4).Value = "Merge Cell 4";
merge1.Add(ws.Range("A" + i + ":B" + (i + 1)));
merge2.Add(ws.Range("C" + i + ":C" + (i + 1)));
merge3.Add(ws.Range("D" + i + ":E" + i));
merge4.Add(ws.Range("D" + (i + 1) + ":E" + (i + 1)));
Console.Clear();
Console.Write(i);
}
// Attempt to merge all cells.
merge1.ForEach(x => x.Merge());
merge2.ForEach(x => x.Merge());
merge3.ForEach(x => x.Merge());
merge4.ForEach(x => x.Merge());
}
wb.SaveAs(@"C:\Test2.xlsm");
}
timer.Stop();
Console.WriteLine("Took {0}s", timer.Elapsed.TotalSeconds);
You can see it takes a while for this to execute.Help is VERY appreciated!
Source code checked in, #eb1ed478e50e157ab61f7e090c09482268912435
New Post: Cell Merge Performance
I don't know about your real code but the example you gave does a whole lot of unnecessary steps. Here's the shorter version:
int total = 5000;
var timer = System.Diagnostics.Stopwatch.StartNew();
using (XLWorkbook wb = new XLWorkbook(XLEventTracking.Disabled))
{
using (var ws = wb.AddWorksheet("MergeCellsWorksheet"))
{
// Insert some values
for (int i = 1; i <= total; i += 2)
{
ws.Cell(i, 1).Value = "Merge Cell 1";
ws.Cell(i, 3).Value = "Merge Cell 2";
ws.Cell(i, 4).Value = "Merge Cell 3";
ws.Cell((i + 1), 4).Value = "Merge Cell 4";
ws.Range("A" + i + ":B" + (i + 1)).Merge(false);
ws.Range("C" + i + ":C" + (i + 1)).Merge(false);
ws.Range("D" + i + ":E" + i).Merge(false);
ws.Range("D" + (i + 1) + ":E" + (i + 1)).Merge(false);
}
}
wb.SaveAs(@"c:\temp\saved.xlsx");
}
timer.Stop();
Console.WriteLine("Took {0}s", timer.Elapsed.TotalSeconds);
Console.WriteLine("Done");
Updated Wiki: Home
Project Description
ClosedXML makes it easier for developers to create Excel 2007/2010 files. It provides a nice object oriented way to manipulate the files (similar to VBA) without dealing with the hassles of XML Documents. It can be used by any .NET language like C# and Visual Basic (VB).
Q: Dude, where have you been?
A: I've been making a survey app called Conspek. It's now open to the public. My hope is that it will be able to pay the bills and allow me to keep working on ClosedXML.
Q: Why a survey tool?
A: The same reason I created ClosedXML, I wasn't happy with my options. A while back I had to create a survey but all online survey apps were fiendishly hard, all so clunky, and with a million options in my face (that I would never use). So I created my own survey tool with the goal of making the experience as easy and simple as possible. Try it out and give me some feedback at conspek.com or better yet, recommend it to someone you know who does surveys ^_^
What can you do with this?
ClosedXML allows you to create Excel 2007/2010 files without the Excel application. The typical example is creating Excel reports on a web server.
If you've ever used the Microsoft Open XML Format SDK you know just how much code you have to write to get the same results as the following 4 lines of code.
var workbook = new XLWorkbook(); var worksheet = workbook.Worksheets.Add("Sample Sheet"); worksheet.Cell("A1").Value = "Hello World!"; workbook.SaveAs("HelloWorld.xlsx");
Something more elaborate:
The Documentation page has an example of how to create the following table (Showcase) as well as many other examples: