I am trying to create a Pivot Table from a full Worksheet with C# interop but I am getting some errors, don't know if is my code or this example is old.
I am following this example: Creating a Pivot Table c#
But when I try it, I can't find some methods.
This is my code:
Microsoft.Office.Interop.Excel.Application Excel = new Microsoft.Office.Interop.Excel.Application();
Workbooks libro = Excel.Workbooks;
Workbook libroActual = libro.Add();
Sheets sheets = libroActual.Worksheets;
//Excel.Workbooks.Add();
// Instanciamos la hora activa
Microsoft.Office.Interop.Excel._Worksheet Worksheet = Excel.ActiveSheet;
Worksheet.Name = "Desglose";
Worksheet sheetMMPP = Excel.Worksheets.Add();
sheetMMPP.Name = "MMPP";// CreateEmptySheet();
Microsoft.Office.Interop.Excel.Range dataRange = Worksheet.UsedRange;
Microsoft.Office.Interop.Excel.PivotCache cache = (Microsoft.Office.Interop.Excel.PivotCache)libroActual.PivotCaches().Add(Microsoft.Office.Interop.Excel.XlPivotTableSourceType.xlDatabase,dataRange);
Microsoft.Office.Interop.Excel.PivotTable pt = (Microsoft.Office.Interop.Excel.PivotTable)sheetMMPP.PivotTables().Add("Pivot Table", Worksheet.Range["A1"], cache);
Microsoft.Office.Interop.Excel.PivotField oPivotField = (Microsoft.Office.Interop.Excel.PivotField)pt.PivotFields("Nivel 0");
oPivotField.Orientation = Microsoft.Office.Interop.Excel.XlPivotFieldOrientation.xlDataField;
oPivotField.Function = Microsoft.Office.Interop.Excel.XlConsolidationFunction.xlSum;
oPivotField.Name = "Nivel 0";
But I get this error:
Could not convert argument 2 for call to Add
The error is in this line:
Microsoft.Office.Interop.Excel.PivotTable pt = (Microsoft.Office.Interop.Excel.PivotTable)sheetMMPP.PivotTables().Add("Pivot Table", Worksheet.Range["A1", "P56"], cache);
Someone knows about this error?
Looks like you've mixed up libraries. In your link, the example is based on the Spire.xls library, but in the code you use Interop.Excel with Spire syntax. The Interop.Excel PivotTables.Add method has different parameters - Add (Microsoft.Office.Interop.Excel.PivotCache PivotCache, object TableDestination, [object TableName], [object ReadData], [object DefaultVersion])
Related
I am writing an application in which I need to store data cell values into excel sheet. Everything is working fine but the problem is everytime I run the application, it overwrites the existing data.
So far the code I have taken from Github:
var workbook = new XLWorkbook();
var worksheet = workbook.Worksheets.Add("Sample Sheet");
worksheet.Cell("A1").Value = this.textBox1.Text;
worksheet.Cell("B1").Value = this.textBox2.Text;
worksheet.Cell("C1").Value = this.textBox3.Text;
worksheet.Cell("D1").Value = col1;
worksheet.Cell("E1").Value = col2;
worksheet.Cell("F1").Value = this.textBox6.Text;
workbook.SaveAs("HelloWorld.xlsx");
Note: I don't want to save data using datatable or anything. I just want to get values from textboxes and append them to the existing sheet. I have visited many stackoverflow post but they doesn't helped me much.
Thanks in advance!
Hope this helps:
var wb = new XLWorkbook("Path to file");
IXLWorksheet Worksheet = wb.Worksheet("Tab name");
int NumberOfLastRow = Worksheet.LastRowUsed().RowNumber();
IXLCell CellForNewData = Worksheet.Cell(NumberOfLastRow + 1, 1);
CellForNewData.InsertData(your_data);
You are explicitly storing the values in row 1 of the spreadsheet. If you want to append the values, you'll have to increment the row number and store the values in the appropriate cells.
I would like to add a column that already contains cells values between two columns (or at the end) of a worksheet of an existing workbook that I load.
So I have a function that sets that "column values" I need :
private static Workbook SetIndicatorsWorkbook()
{
var workbook = new Workbook(WorkbookFormat.Excel2007MacroEnabled);
var worksheet = workbook.Worksheets.Add("Unit & Integration Tests");
//Don't worry about team and jenkinsBuilTeams variables
foreach (var team in jenkinsBuildTeams)
{
worksheet.Rows[posX].Cells[0].Value = lastnbUnitTests + lastnbIntegrationTests;
posX += 1;
}
return workbook;
}
And then in main function I want to add this column (which is workbook.worksheets[0].Columns[0] ) in a loaded workbook :
private static void Main()
{
//The workbook I need to update
Workbook workbook = Workbook.Load("file.xlsx");
Workbook temp = SetIndicatorsWorkbook();
WorksheetColumn wc = temp.Worksheets[0].Columns[0];
//The issue is that Worksheet's Columns collection has no "Insert" property
workbook.Save("file.xlsx");
}
The Columns collection of the Worksheet has an Insert method that will shift data/formatting just as would happen in Excel. This was added in the 2014 volume 2 version. You can read more about that in the help topic or the api documentation. Note I've linked to the WPF version help but the Insert method is available in the other platforms as well.
I have the following error...
System.Data.DuplicateNameException: 'A column named 'samplex' already
belongs to this DataTable.'
I have large multiple excel files that need merging into one. But all the column names are the same. So I think that is why I am getting this error.
All the data is in sheet1 one from each excel files. Searching on the net the best one I found was using Spire.Xls, sample taken from here
My code sample, using console...
using Spire.Xls;
::
::
Workbook workbook = new Workbook();
workbook.LoadFromFile(#"filea.xlsx");
Workbook workbook2 = new Workbook();
workbook2.LoadFromFile(#"fileb.xlsx");
Workbook workbook3 = new Workbook();
workbook3.LoadFromFile(#"filec.xlsx");
Worksheet sheet2 = workbook3.Worksheets[0];
DataTable dataTable = sheet2.ExportDataTable();
Worksheet sheet1 = workbook.Worksheets[0];
sheet1.InsertDataTable(dataTable, false, sheet1.LastRow + 1, 1);
//save the workbook
workbook.SaveToFile("result.xlsx");
Appreciate if anyone can help me on this?
Since you're able to get DataTable objects and all the column names are the same, I'd bet you could use DataTable.Merge() -
Workbook workbook1 = ...;
Workbook workbook2 = ...;
DataTable bookTable1 = workbook1.ExportDataTable();
DataTable booktable2 = workbook2.ExportDataTable();
bookTable1.Merge(bookTable2);
// Spire specific API calls to save bookTable1 to Excel file
The only requirement for your data is that you have a key column. To configure the DataTable with a key -
bookTable1.PrimaryKey = bookTable1.Columns("DataID" /* your key column name here */);
When I used Microsoft.Office.Interop.Excel, sample taken from here, it solve the problem regarding columns with same name. The code is long and complicated but it works but you will need Microsoft Office on the machine. Only a slight problem is that the results shows in new sheet, it doesn't go directly into sheet1. If anyone can advise me on this, it will be ideal.
I am using Visual Studio 2017.
You can use CellRange.Copy(CellRange destRange) method in Spire.XLS to merge worksheets from different workbooks into one, it won't throw the DuplicateNameException.
Refer to the following code:
//Load the first workbook
Workbook workbook1 = new Workbook();
workbook1.LoadFromFile("Sample.xlsx");
Worksheet sheet1 = workbook1.Worksheets[0];
//Load the second workbook
Workbook workbook2 = new Workbook();
workbook2.LoadFromFile("sample2.xlsx");
Worksheet sheet2 = workbook2.Worksheets[0];
int a = sheet2.LastRow;
int b = sheet2.LastColumn;
//Copy data from the 2nd row in sheet2 into sheet1
sheet2.Range[2, 1, a, b].Copy(sheet1.Range[sheet1.LastRow + 1, 1, a + sheet1.LastRow, b]);
workbook1.SaveToFile("reslut.xlsx", ExcelVersion.Version2013);
I have already tried the code and it works well on my side.
Using OpenXml on a excel sheet i create new worksheet.
newWorksheetPart.Worksheet = new Worksheet(new SheetData());
Sheet sheet = new Sheet()
{ Id = relationshipId, SheetId = sheetId, Name = sheetName };
workBookSheets.Append(sheet);
How do i move this newly created worksheet in the place of a another worksheet ?
For example :There are three worksheets
A,B,C and i create a new worksheet A1 and want A1 to be in the place of B . How do i go about this ?
Thanks
I believe you can do something like this:
document.WorkbookPart.Workbook.Sheets.InsertBefore(sheet, sheetB);
Where "sheetB" would be the OpenXMLElement. So rather than appending the sheet to the workbook you would insert sheet A1 before sheet B.
I was able to make a sheet the first in the workbook by doing the following:
document.WorkbookPart.Workbook.Sheets.InsertBefore(sheet,
document.WorkbookPart.Workbook.Sheets.FirstChild);
I'm having an issue with a very basic thing. Deleting a table using EPPlus.
The problem that I'm facing is that from the code point of view (I've debugged the code, and in the Worksheet.Tables collection, the tabled that I called Delete on is gone. I proceed to save the excel and when I try to open it, Excel tells me that "they" found a problem with it, and if I want them to recover as much as possible. If I select Yes (because No closes the file) the table that I just delete through code is back again.
If I set the ClearRange property in the Delete() method to true, the table is still in the spreadsheet, but this time the header columns are gone, and instead Excel recreates my table with some default names (Column1, Column2, etc, depending on the number of columns the original table had).
I've tried to manipulate the TableXml property of the table, and it's still not working. Other than that, I've just read the Internet for about 3 hours with no apparent solution to my problem.
So, if anyone is wondering, the code for this is:
using (var package = new ExcelPackage(fileToWriteTo, templateToStartWith))
{
var workbook = package.Workbook;
var worksheet = workbook.Worksheets[WORKSHEET_NAME];
worksheet.Tables.Delete("dynamicTable", true);
//worksheet.Tables.Delete("dynamicTable");
package.Save();
}
As you can see, a very basic operation that kinda fails.
If anyone knows of a solution to remove a table from a spreadsheet with EPPlus, please share. Would be much appreciated.
I have trouble with the Delete method as well. I can't even compile when I reference it half the time. Strange.
What if you delete the reference to the table via xml. If it is the only table in the ws or you know the exact order it is pretty easy to do:
[TestMethod]
public void Table_Delete_Test()
{
//http://stackoverflow.com/questions/36359047/unable-to-delete-table-using-epplus
//Throw in some data
var datatable = new DataTable("tblData");
datatable.Columns.AddRange(new[]
{
new DataColumn("Col1", typeof (int)), new DataColumn("Col2", typeof (int)), new DataColumn("Col3", typeof (object))
});
for (var i = 0; i < 10; i++)
{
var row = datatable.NewRow();
row[0] = i; row[1] = i * 10; row[2] = Path.GetRandomFileName();
datatable.Rows.Add(row);
}
var fi = new FileInfo(#"c:\temp\Table_Delete_Test.xlsx");
if (fi.Exists)
fi.Delete();
//Create a worksheet with tables to later open and look for tables (note that EPPlus does not create the table objects until save)
using (var pck = new ExcelPackage(fi))
{
var workbook = pck.Workbook;
var worksheet = workbook.Worksheets.Add("source");
worksheet.Cells["A1"].LoadFromDataTable(datatable, true);
worksheet.Cells["A12"].LoadFromDataTable(datatable, true);
var table1 = worksheet.Tables.Add(worksheet.Cells["A1:C11"], "TableTest1");
var table2 = worksheet.Tables.Add(worksheet.Cells["A12:C22"], "TableTest2");
pck.Save();
}
//Open the test workbook and delete the second table
using (var pck = new ExcelPackage(fi))
{
var workbook = pck.Workbook;
var worksheet = workbook.Worksheets.First();
var wsXml = worksheet.WorksheetXml;
var nsm = new XmlNamespaceManager(wsXml.NameTable);
var nsuri = wsXml.DocumentElement.NamespaceURI;
nsm.AddNamespace("m", nsuri);
//Remove reference to the second table which should be last
var tablePartsNode = wsXml.SelectSingleNode("m:worksheet/m:tableParts", nsm);
tablePartsNode.RemoveChild(tablePartsNode.LastChild);
pck.Save();
}
}
So it goes from this:
to this:
But if you need to do it by Table.Name that is not so easy. You would have to get the RelationshipID which Epplus has marked as internal. The RID is based on the zip package so to get that you either fork and modify Epplus to expose it or you open the XLSX as a ZipArchive and get the RID from that - kind of a pain.