I am creating a excel sheet from tempalte excel sheet.
I have a code
try
{
FileInfo newFile = new FileInfo(#"D:\ExcelFromTemplate.xlsx");
FileInfo template = new FileInfo(#"D:\template.xlsx");
using (ExcelPackage xlPackage = new ExcelPackage(newFile, template))
{
ExcelWorksheet worksheet = xlPackage.Workbook.Worksheets["Sheet1"];
ExcelCell cell = worksheet.Cell(5,1);
cell.Value = "15";
//worksheet.Cell(5, 1).Value = "Soap";
//xlPackage.Save();
Response.Write("Excel file created successfully");
}
}
catch (Exception ex)
{
Response.WriteFile(ex.InnerException.ToString());
}
this code creates the new excel file same as the template excel file but could not add the cell value. Why?
I had tried it with 2 ways as in above code for cell(5,1). But the excel sheet creates without writting cell value. How we can add it.
You need to save the file to persist the changes made. Using save()
try
{
FileInfo newFile = new FileInfo(#"D:\ExcelFromTemplate.xlsx");
FileInfo template = new FileInfo(#"C:\Example.xlsx");
using (ExcelPackage xlPackage = new ExcelPackage(newFile , template))
{
//Added This part
foreach (ExcelWorksheet aworksheet in xlPackage.Workbook.Worksheets)
{
aworksheet.Cell(1, 1).Value = aworksheet.Cell(1, 1).Value;
}
ExcelWorksheet worksheet = xlPackage.Workbook.Worksheets["My Data"];
ExcelCell cell = worksheet.Cell(5, 1);
cell.Value = "15";
//worksheet.Cell(5, 1).Value = "Soap";
xlPackage.Save( );
//Response.Write("Excel file created successfully");
}
}
catch (Exception ex)
{
//Response.WriteFile(ex.InnerException.ToString());
}
Got the issue. The problem is inherent to ExcelPackage.
For the same you have to open each sheet and do some changes for it to get saved.
Search the forum for more explanation.
Related
As question, How to convert excel in API and transfer as file back to the service?
Currently I able to get the data from database already but after getting the data from it, I'm not sure how to convert the data to excel before send back to the service. I need to convert it in api instead of in angular component side after getting the full completed of data from API.
[Route("getExcelData")]
[Authenticate]
[HttpPost]
public IHttpActionResult GetExcelData([FromBody]Report obj)
{
try
{
this.Contents.Add("Result", new ReportService().getExcelData(obj.Id, obj.FromDate, obj.ToDate));
return JsonResponse();
}
catch (Exception e)
{
LogManager.Instance.InsertLog(LogLevel.Error, e.Message, e.StackTrace, "ReportController", "ReportController", null, null);
ExceptionManager.Instance.Add(String.Format("GetData Failed: {0}", e.Message), $"{e.StackTrace} Inner Exception: {e.InnerException}");
this.Contents.Add("Result", null);
return JsonResponse();
}
}
Below code worked for me.
please find more elobarations here.
#region Loading the data to DataGridView
DataSet customersDataSet = new DataSet();
//Read the XML file with data
string inputXmlPath = Path.GetFullPath(#"../../Data/Employees.xml");
customersDataSet.ReadXml(inputXmlPath);
DataTable dataTable = new DataTable();
//Copy the structure and data of the table
dataTable = customersDataSet.Tables[1].Copy();
//Removing unwanted columns
dataTable.Columns.RemoveAt(0);
dataTable.Columns.RemoveAt(10);
this.dataGridView1.DataSource = dataTable;
dataGridView1.AlternatingRowsDefaultCellStyle.BackColor = Color.White;
dataGridView1.RowsDefaultCellStyle.BackColor = Color.LightBlue;
dataGridView1.ColumnHeadersDefaultCellStyle.Font = new System.Drawing.Font("Tahoma", 9F, ((System.Drawing.FontStyle)(System.Drawing.FontStyle.Bold)));
dataGridView1.ForeColor = Color.Black;
dataGridView1.BorderStyle = BorderStyle.None;
#endregion
using (ExcelEngine excelEngine = new ExcelEngine())
{
IApplication application = excelEngine.Excel;
//Create a workbook with single worksheet
IWorkbook workbook = application.Workbooks.Create(1);
IWorksheet worksheet = workbook.Worksheets[0];
//Import from DataGridView to worksheet
worksheet.ImportDataGridView(dataGridView1, 1, 1, isImportHeader: true, isImportStyle: true);
worksheet.UsedRange.AutofitColumns();
workbook.SaveAs("Output.xlsx");
}
I'm creating an xlsx file in my application with openXML. The file is created but when I want to open it with excel 2019 (I didn't try another excel) I have an error message that there is a problem.
Thus I say "Yes" to repair the file and thus excel says "repaired record : sheet properties in the /xl/workbook.xml part".
Note that I use the almost same code to create xlsx file in an other part of the app and it works without error. the difference is that I'm working on a List> in the new part.
I tried to replace append by appendChild but I have an exception error.
I tried to rearrange code lines to change the order creation of the different parts but always excel error.
public static byte[] ToOpenXml(HttpContext context, List<List<String>> data, String fileName, Boolean hasCount)
{
Shared sharedClass = new Shared();
using (MemoryStream memoryStream = new MemoryStream())
{
using (SpreadsheetDocument xlsxDocument = SpreadsheetDocument.Create(memoryStream, SpreadsheetDocumentType.Workbook))
{
WorkbookPart workbookPart = xlsxDocument.AddWorkbookPart();
Workbook workbook = new Workbook();
workbookPart.Workbook = workbook;
Sheets sheets = new Sheets();
workbook.Append(sheets);
Sheet sheet = new Sheet()
{
Name = fileName,
SheetId = 1,
Id = "rId1"
};
sheets.Append(sheet);
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>("rId1");
Worksheet worksheet = new Worksheet();
SheetData sheetData = new SheetData();
worksheet.Append(sheetData);
worksheetPart.Worksheet = worksheet;
//Index initialization
UInt32 rowIndex = 1;
Row row = new Row()
{
RowIndex = rowIndex
};
String value = String.Empty;
foreach (List<String> datum in data)
{
UInt32 columnDataIndex = 1;
row = new Row()
{
RowIndex = rowIndex
};
for (Int32 i = 0; i < datum.Count; i++)
{
Cell cell = CreateCell(columnDataIndex, rowIndex, CellValues.String, datum[i]);
row.Append(cell);
columnDataIndex = columnDataIndex + 1;
}
sheetData.Append(row);
rowIndex = rowIndex + 1;
}
}
return memoryStream.ToArray();
}
}
public static Cell CreateCell(uint columnDataIndex, uint rowIndex, CellValues format, object value)
{
string columnDataLetter = ColumnIndexToColumnLetter(columnDataIndex);
String cellValue = "";
Cell cell = new Cell()
{
CellReference = columnDataLetter + rowIndex,
DataType = CellValues.String
};
switch (format)
{
case CellValues.Date:
DateTime date = new DateTime();
try
{
date = (DateTime)value;
}
catch (Exception e)
{
}
cellValue = date.ToString(CultureInfo.InvariantCulture);
break;
default:
cellValue = (String)value;
break;
}
cell.CellValue = new CellValue(cellValue);
return cell;
}
The xlsx file is created but when I open it I have to repair the file and "repaired record : sheet properties in the /xl/workbook.xml part".
I would like to open in excel 2019 (the only one I tested) without error.
Thank you for helping me.
Finally, I solved the problem.
The problem was due to the sheet name. I put the filename in it but the file name was longer than 31 characters which is the max length of a sheet name in excel file.
I added this code line before the first using :
String sheetName = fileName.Substring(0,30);
and I put it in the declaration sheet :
Sheet sheet = new Sheet()
{
Name = sheetName,
SheetId = 1,
Id="rId1"
};
Hello so I was given a Project were I needed to read a xlsm file and then Project the result into a DataGripView, this is what I have so far.
var filename = "Filename|.xlsm"
XLWorkbook workbook = null;
try
{
workbook = new XLWorkbook(filename);
}
catch (Exception)
{
labelResult.Text = "error message";
return;
}
IXLWorksheet ws = null;
bool success = workbook.Worksheets.TryGetWorksheet("Cell", out ws);
if(!success)
{
labelResult.Text = "error message.";
return;
}
List<MyList> listnum = new List<MyList>();
foreach (var row in ws.RowsUsed())
{
MyList ML = new MyList { };
ML.statecod = row.Cell(1).GetString();
ML.state = row.Cell(2).GetString();
dataGridView1.DataSource = listnum;
}
So how do I populate my datagridview with the data from a xlsm file without having excel installed, therefore no excel libraries and no use of oledb?
So I found the answer. Just needed to add: listnum.add(ML);
I forgot to add my list, silly me...
I am developing one WPF application (using MVVM). I am also able to export my List to Excel file.But my problem is I am not able to make it readonly, so no one can able to make changes afterwards.
document.WorkbookPart.Workbook.WorkbookProtection=new WorkbookProtection
{
LockStructure=true
};
I only found this, but it's only make workbook readonly
Here is my code for creating excel file
public static bool CreateExcelDocument(DataSet ds, string excelFilename)
{
try
{
using (SpreadsheetDocument document = SpreadsheetDocument.Create(excelFilename, SpreadsheetDocumentType.Workbook))
{
document.AddWorkbookPart();
document.WorkbookPart.Workbook = new DocumentFormat.OpenXml.Spreadsheet.Workbook();
document.WorkbookPart.Workbook.WorkbookProtection=new WorkbookProtection
{
LockStructure = true,
};
// My thanks to James Miera for the following line of code (which prevents crashes in Excel 2010)
document.WorkbookPart.Workbook.Append(new BookViews(new WorkbookView()));
// If we don't add a "WorkbookStylesPart", OLEDB will refuse to connect to this .xlsx file !
WorkbookStylesPart workbookStylesPart = document.WorkbookPart.AddNewPart<WorkbookStylesPart>("rIdStyles");
Stylesheet stylesheet = new Stylesheet();
workbookStylesPart.Stylesheet = stylesheet;
CreateParts(ds, document);
}
Trace.WriteLine("Successfully created: " + excelFilename);
return true;
}
catch (Exception ex)
{
Trace.WriteLine("Failed, exception thrown: " + ex.Message);
return false;
}
}
private static void CreateParts(DataSet ds, SpreadsheetDocument spreadsheet)
{
// Loop through each of the DataTables in our DataSet, and create a new Excel Worksheet for each.
uint worksheetNumber = 1;
foreach (DataTable dt in ds.Tables)
{
// For each worksheet you want to create
string workSheetID = "rId" + worksheetNumber.ToString();
string worksheetName = dt.TableName;
WorksheetPart newWorksheetPart = spreadsheet.WorkbookPart.AddNewPart<WorksheetPart>();
newWorksheetPart.Worksheet = new DocumentFormat.OpenXml.Spreadsheet.Worksheet();
// create sheet data
newWorksheetPart.Worksheet.AppendChild(new DocumentFormat.OpenXml.Spreadsheet.SheetData());
// save worksheet
WriteDataTableToExcelWorksheet(dt, newWorksheetPart);
newWorksheetPart.Worksheet.Save();
// create the worksheet to workbook relation
if (worksheetNumber == 1)
spreadsheet.WorkbookPart.Workbook.AppendChild(new DocumentFormat.OpenXml.Spreadsheet.Sheets());
spreadsheet.WorkbookPart.Workbook.GetFirstChild<DocumentFormat.OpenXml.Spreadsheet.Sheets>().AppendChild(new DocumentFormat.OpenXml.Spreadsheet.Sheet()
{
Id = spreadsheet.WorkbookPart.GetIdOfPart(newWorksheetPart),
SheetId = (uint)worksheetNumber,
Name = dt.TableName
});
worksheetNumber++;
}
spreadsheet.WorkbookPart.Workbook.Save();
}
Before you open Excel, you can Lock your file with:
FileInfo cInfo = new FileInfo(Path);
cInfo.IsReadonly = true;
Than it will be readonly.
I've found how to read first line from Excel file with specific sheet name, but in my case I have to read first line of the first sheet.
How can I realize that or I have to use CSV instead of XLS?
Did you take a look at the EPPlus library? It makes very easy to work with excel files.
Here is how you would do that using EPPlus:
FileInfo existingFile = new FileInfo("yourfilepathname");
using (var package = new ExcelPackage(existingFile))
{
ExcelWorkbook workbook = package.Workbook;
if (workbook != null && workbook.Worksheets.Count > 0)
{
//Gets the first worksheet. You can use index also to select your worksheet.
ExcelWorksheet worksheet = workbook.Worksheets.First();
int rowIndex = 0;
int colIndex = 0;
//To get the first cell:
var cellValue = worksheet.Cells[rowIndex, colIndex].Value;
//YOU CAN ALSO DO A LOOP TO GET ALL VALUES FROM THE FIRST ROW.
}
}
NPOI is another good option and it can handle XLS files too.
Here's a snippet of NPOI code:
HSSFWorkbook _hssfworkbook = new HSSFWorkbook(OpenFileStream(filePath));
//Getting the sheet
_currentSheet = _hssfworkbook.GetSheetAt(0);
//Getting the row:
_row = CurrentSheet.GetRow(0);
//Getting the cell
_cell = _row.GetCell(0);
Have you considered SpreadsheetLight? Here's how you do it:
SLDocument sl = new SLDocument("YourExcelFile.xlsx", "TheSheetName");
string FirstLine = sl.GetCellValueAsString("A1");
sl.CloseWithoutSaving();
Disclaimer: I wrote SpreadsheetLight.