I've been following this guide https://msdn.microsoft.com/EN-US/library/office/cc861607.aspx to insert a string to a cell in an excel file. The example is really confusing, and even when i copy/paste it doesn't work. I'm looking for a very simple example to insert a a value into a cell like:
spredSheet.InsertCell("A", 1, string value)
I could really use a simple code example showing me how to insert data into a cell using OpenXML in asp.net.
I tried the code from this post Using OpenXML to insert a datatable into excel, but it creates a broken excel file.
This is how my code look without the helper functions from the link
using (SpreadsheetDocument myDoc = SpreadsheetDocument.
Create(Server.MapPath("/data.xls"), SpreadsheetDocumentType.Workbook))
{
WorkbookPart workbookpart = myDoc.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
// Add a WorksheetPart to the WorkbookPart.
WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
//add column names to the first row
Row header = new Row();
header.RowIndex = (UInt32)1;
SheetData sheetData = new SheetData();
Cell headerCell = createTextCell(1, 1, text);
header.AppendChild(headerCell);
sheetData.AppendChild(header);
// Add a WorkbookPart to the document.
worksheetPart.Worksheet = new Worksheet(sheetData);
}
The MSDN example is using SpreadsheetDocument.Open which opens an existing file but you are creating a brand new file with SpreadsheetDocument.Create. When you create a brand new file there are certain elements you must create in order for the file to be valid. The elements you are missing are the Sheets and Sheet elements.
Sheets are stored separately from the SheetData so you need to create a Sheet inside a Sheets and then associate the Sheets with the WorksheetPart.
This can be done like so:
Sheets sheets = myDoc.WorkbookPart.Workbook.AppendChild(new Sheets());
sheets.AppendChild(new Sheet()
{
Id = myDoc.WorkbookPart.GetIdOfPart(myDoc.WorkbookPart.WorksheetParts.First()),
SheetId = 1,
Name = "Sheet1"
});
So your full code listing would be something like:
using (SpreadsheetDocument myDoc = SpreadsheetDocument.
Create(Server.MapPath("/data.xls"), SpreadsheetDocumentType.Workbook))
{
WorkbookPart workbookpart = myDoc.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
// Add a WorksheetPart to the WorkbookPart.
WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
//add column names to the first row
Row header = new Row();
header.RowIndex = (UInt32)1;
SheetData sheetData = new SheetData();
Cell headerCell = createTextCell(1, 1, text);
header.AppendChild(headerCell);
sheetData.AppendChild(header);
// Add a WorkbookPart to the document.
worksheetPart.Worksheet = new Worksheet(sheetData);
//this is the part that was missing from your code
Sheets sheets = myDoc.WorkbookPart.Workbook.AppendChild(new Sheets());
sheets.AppendChild(new Sheet()
{
Id = myDoc.WorkbookPart.GetIdOfPart(myDoc.WorkbookPart.WorksheetParts.First()),
SheetId = 1,
Name = "Sheet1"
});
}
Related
I'm using ClosedXML library to generate a simple Excel file with 2 worksheets.
I keep getting error message whenever i try to open the file saying
"We found a problem with some content in "example.xlsx". Do you want us to try to recover as much as we can. if you trust source of this workbook, click Yes"
If i click Yes, it displays the data as expected, i don't see any
problems with it. Also if i generate only 1 worksheet this error does
not appear.
This is what my stored procedure returns, first result set is populated in sheet1 and second result set is populated in sheet2, which works as expected.
Workbook data
Here is the method i am using, it returns 2 result sets and populates both result sets in 2 different worksheets:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult POAReport(POAReportVM model)
{
POAReportVM poaReportVM = reportService.GetPOAReport(model);
using (var workbook = new XLWorkbook())
{
IXLWorksheet worksheet1 = workbook.Worksheets.Add("ProductOrderAccuracy");
worksheet1.Cell("A1").Value = "DATE";
worksheet1.Cell("B1").Value = "ORDER";
worksheet1.Cell("C1").Value = "";
var countsheet1 = 2;
for (int i = 0; i < poaReportVM.productOrderAccuracyList.Count; i++)
{
worksheet1.Cell(countsheet1, 1).Value = poaReportVM.productOrderAccuracyList[i].CompletedDate.ToString();
worksheet1.Cell(countsheet1, 2).Value = poaReportVM.productOrderAccuracyList[i].WebOrderID.ToString();
worksheet1.Cell(countsheet1, 3).Value = poaReportVM.productOrderAccuracyList[i].CompletedIndicator;
countsheet1++;
}
IXLWorksheet worksheet2 = workbook.Worksheets.Add("Summary");
worksheet2.Cell("A1").Value = "Total Orders Sampled";
worksheet2.Cell("B1").Value = "Passed";
worksheet2.Cell("C1").Value = "% Passed";
worksheet2.Cell(2, 1).Value = poaReportVM.summaryVM.TotalOrdersSampled.ToString();
worksheet2.Cell(2, 2).Value = poaReportVM.summaryVM.Passed.ToString();
worksheet2.Cell(2, 3).Value = poaReportVM.summaryVM.PassedPercentage.ToString();
//save file to memory stream and return it as byte array
using (var ms = new MemoryStream())
{
workbook.SaveAs(ms);
ms.Position = 0;
var content = ms.ToArray();
return File(content, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
}
}
}
I had similar problem. For me the cause was as mentioned in this answer:
I had this issue when I was using EPPlus to customise an existing template. For me the issue was in the template itself as it contained invalid references to lookup tables. I found this in Formula -> Name Manager.
You may find other solutions there.
Apologies as my reputation is too low to add a comment.
I have a text file that contains around 21 lac entries and I want to insert all these entries into a table. Initially I have created one function in c# that read line by line and insert into table but it takes too much time. Please suggest an efficient way to insert these bulk data and that file is containing TAB(4 spaces) as delimiter.
And that text file also containing some duplicate entries and I don't want to insert those entries.
Load all of your data into a DataTable object and then use SqlBulkCopy to bulk insert them:
DataTable dtData = new DataTable("Data");
// load your data here
using (SqlConnection dbConn = new SqlConnection("db conn string"))
{
dbConn.Open();
using (SqlTransaction dbTrans = dbConn.BeginTransaction())
{
try
{
using (SqlBulkCopy dbBulkCopy = new SqlBulkCopy(dbConn, SqlBulkCopyOptions.Default, dbTrans))
{
dbBulkCopy.DestinationTableName = "intended SQL table name";
dbBulkCopy.WriteToServer(dtData );
}
dbTrans.Commit();
}
catch
{
dbTrans.Rollback();
throw;
}
}
dbConn.Close();
}
I've included the example to wrap this into a SqlTransaction so there will be a full rollback if there's a failure along the way. To get you started, here's a good CodeProject article on loading the delimited data into a DataSet object.
Sanitizing the data before loading
OK, here's how I think your data looks:
CC_FIPS FULL_NAME_ND
AN Xixerella
AN Vila
AN Sornas
AN Soldeu
AN Sispony
... (cut down for brevity)
In this instance you want to create your DataTable like this:
DataTable dtData = new DataTable("Data");
dtData.Columns.Add("CC_FIPS");
dtData.Columns.Add("FULL_NAME_ND");
Then you want to iterate each row (assuming your tab delimited data is separated row-by-row by carriage returns) and check whether this data already exists in the DataTable using the .Select method and if there is a match (i'm checking for BOTH values, it's up to you whether you want to do something else) then don't add it thereby preventing duplicates.
using (FileStream fs = new FileStream("path to your file", FileMode.Open, FileAccess.Read))
{
int rowIndex = 0;
using (StreamReader sr = new StreamReader(fs))
{
string line = string.Empty;
while (!sr.EndOfStream)
{
line = sr.ReadLine();
// use a row index to skip the header row as you don't want to insert CC_FIPS and FULL_NAME_ND
if (rowIndex > 0)
{
// split your data up into a 2-d array tab delimited
string[] parts = line.Split('\t');
// now check whether this data has already been added to the datatable
DataRow[] rows = dtData.Select("CC_FIPS = '" + parts[0] + "' and FULL_NAME_ND = '" + parts[1] + "'");
if (rows.Length == 0)
{
// if there're no rows, then the data doesn't exist so add it
DataRow nr = dtData.NewRow();
nr["CC_FIPS"] = parts[0];
nr["FULL_NAME_ND"] = parts[1];
dtData.Rows.Add(nr);
}
}
rowIndex++;
}
}
}
At the end of this you should have a sanitized DataTable that you can bulk insert. Please note that this code isn't tested, but it's a best guess as to how you should do it. There are many ways this can be done, and probably a lot better than this method (specifically LINQ) - but it's a starting point.
My Requirement is to read text file, the text file format is
12345|566437347|34564564|66465^2343|234234|45455|4534643...
This text file I need to store into the Excel file. In the text file "^" is the row separator and "|" is the column separator .
You can read the text file into a string and split the string twice:
string[] rowArray = textfile.Split('^');
foreach (string row in rowArray )
{
//excel code
string[] columnArray = textfile.Split('|');
foreach (string column in columnArray )
{
//excel code
}
}
First you split the text-file to rows and then split each rows to columns.
I can recommend EPPLus to create excel files without having Office installed on the server. Then all you need is a DataTable and the LoadFromDataTable method.
You need to split the Text by '^' to get all lines and each line by '|' to get all fields. To get the number of columns of the DataTable, you need to find the maximum count of fields in al lines:
var text = File.ReadAllText(#"C:\Temp\data.txt");
var lines = text.Split('^');
var rows = lines.Select(l => new { Line = l, Fields = l.Split('|') });
var colCount = rows.Max(r => r.Fields.Length);
var tbl = new DataTable();
for (int i = 1; i <= colCount; i++)
tbl.Columns.Add("Column" + i, typeof(string));
foreach (var row in rows)
{
tbl.Rows.Add().ItemArray = row.Fields;
}
var pck = new OfficeOpenXml.ExcelPackage(new FileInfo(#"C:\Temp\data.xlsx"));
var ws = pck.Workbook.Worksheets.Add("Data");
ws.Cells["A1"].LoadFromDataTable(tbl, true, OfficeOpenXml.Table.TableStyles.Medium6);
pck.Save();
I'm using PHPExcel library for many Excel manipulations, combined with PHP/MySQL.
That helps me well.
But I can't figure how to split an Excel document sheet by sheet,where each sheet is created as a new Excel document.
I also need, at the same time, to delete the empty lines which are in the original document in the new Excel documents produced (cleaning up the final docs).
What's the best way to do it ?
All your experiences are greatly appreciated.
Best regards.
I have found the way of what I wanted.
Here is a solution (maybe not the best way, but it works fine enough) :
$file = $_POST['file'];
$filename = pathinfo($file, PATHINFO_FILENAME);
require_once 'phpexcel/Classes/PHPExcel.php';
$xls = new PHPExcel();
$xlsReader= new PHPExcel_Reader_Excel5();
$xlsTemplate = $xlsReader->load($file);
$sheet1 = $xlsTemplate->getSheetByName('Sheet1');
$xls->addExternalSheet($sheet1,0);
$xls->removeSheetByIndex(1);
$xlsWriter = new PHPExcel_Writer_Excel5($xls);
$xlsWriter->save($filename."_Sheet1.xls");
$sheet2 = $xlsTemplate->getSheetByName('Sheet2');
$xls->addExternalSheet($sheet2,0);
$xls->removeSheetByIndex(1);
$xlsWriter = new PHPExcel_Writer_Excel5($xls);
$xlsWriter->save($filename."_Sheet2.xls");
$sheet3 = $xlsTemplate->getSheetByName('Sheet3');
$xls->addExternalSheet($sheet3,0);
$xls->removeSheetByIndex(1);
$xlsWriter = new PHPExcel_Writer_Excel5($xls);
$xlsWriter->save($filename."_Sheet3.xls");
$sheet4 = $xlsTemplate->getSheetByName('Sheet4');
$xls->addExternalSheet($sheet4,0);
$xls->removeSheetByIndex(1);
$xlsWriter = new PHPExcel_Writer_Excel5($xls);
$xlsWriter->save($filename."_Sheet4.xls");
$sheet5 = $xlsTemplate->getSheetByName('Sheet5');
$xls->addExternalSheet($sheet5,0);
$xls->removeSheetByIndex(1);
$xlsWriter = new PHPExcel_Writer_Excel5($xls);
$xlsWriter->save($filename."_Sheet5.xls");
$sheet6 = $xlsTemplate->getSheetByName('Sheet6');
$xls->addExternalSheet($sheet6,0);
$xls->removeSheetByIndex(1);
$xlsWriter = new PHPExcel_Writer_Excel5($xls);
$xlsWriter->save($filename."_Sheet6.xls");
Then, my original Excel file, containing 6 sheets is now splitted in 6 Excel files, as I wanted.
As you can see, it was not so hard to release, but the documentation is so confusing...
Hope this can help.
I am using the ExcelPackage dll to creating the excel from the .net application.
I want to add drop down list in one of column of Excel sheet. How to add it?
Also I want to do some formatting changes to the cell values.
Try spreadsheetgear
....
protected void AddDropDownToExcel(string path)
{
//path gives the location where u have created excel file
string fileName = path.Replace("\\", "\\\\");
// F is the column name where you want to place the dropdown
string RowCount = "F" + gridrowcount;
// Open Excel and get first worksheet.
var workbook = application.Workbooks.Open(fileName);
var worksheet = workbook.Worksheets[1] as Microsoft.Office.Interop.Excel.Worksheet;
// Set range for dropdownlist
var rangeNewStatus = worksheet.get_Range("F2", RowCount);
rangeNewStatus.ColumnWidth = 20;
rangeNewStatus.Validation.Add(Microsoft.Office.Interop.Excel.XlDVType.xlValidateList, Microsoft.Office.Interop.Excel.XlDVAlertStyle.xlValidAlertStop,
Microsoft.Office.Interop.Excel.XlFormatConditionOperator.xlBetween, "dropdownlistitem1, dropdownlistitem2");
// Save.
workbook.Save();
workbook.Close(Microsoft.Office.Interop.Excel.XlSaveAction.xlSaveChanges, Type.Missing, Type.Missing);
application.Quit();
}