I make to get data excel with C# winform.
private void ReleaseExcelObject(object obj)
{
try
{
if (obj != null)
{
Marshal.ReleaseComObject(obj);
obj = null;
}
}
catch (Exception ex)
{
obj = null;
throw ex;
}
}
private void buttonOpen_Click(object sender, EventArgs e)
{
Microsoft.Office.Interop.Excel.Application application = null;
Workbook workBook = null;
int tempNum = 0;
try
{
OpenFileDialog dlg = new OpenFileDialog();
if (dlg.ShowDialog() != DialogResult.OK)
return;
application = new Microsoft.Office.Interop.Excel.Application();
application.Visible = true;
workBook = application.Workbooks.Open(dlg.FileName);
Worksheet newWorkSheet = workBook.Worksheets.Add(After: workBook.Worksheets.Item[workBook.Worksheets.Count]);
int newSheetRow = 0;
Dictionary<int, string> upData = new Dictionary<int, string>();
for (int sheetIndex = 1; sheetIndex<workBook.Worksheets.Count; sheetIndex++)
{
for (int row = 1; row < workBook.Worksheets[sheetIndex].UsedRange.Rows.Count; row++)
{
upData.Add(row, null);
for (int col = 1; col < workBook.Worksheets[sheetIndex].UsedRange.Columns.Count; col++)
{
tempNum++;
if (workBook.Worksheets[sheetIndex].Cells[col, row] != null)
{
string cellData = workBook.Worksheets[sheetIndex].Cells[col, row].value;
string[] datas = cellData.Split(' ');
string dataName = null;
for (int k = 1; k < datas.Length; k++)
{
dataName += datas[k];
}
string icd11 = datas[0];
newWorkSheet.Cells[newSheetRow,0] = icd11;
newWorkSheet.Cells[newSheetRow,1] = dataName;
newWorkSheet.Cells[newSheetRow,2] = upData[col - 1];
upData[col] = dataName;
continue;
}
}
}
}
}
catch (Exception exc)
{
MessageBox.Show(tempNum + exc.Message);
}
finally
{
ReleaseExcelObject(workBook);
ReleaseExcelObject(application);
}
}
The part where the error occurs is
MessageBox.Show(workBook.Sheets[0].ToString());
this part.
And force workBookSheet.getitem("hardCording").
If you do this, an error occurs in the part of direct data access of the cell.
I wonder how I can query and insert excel data.
The error is Invalid index. (Exception from HRESULT: 0x8002000B (DISP_E_BADINDEX))
Excel data:
edit sheet[0]
sheet[0] is not able
i don't understand VBA
how to implement this
excel treeExample
Worksheet newWorkSheet = workBook.Worksheets.Add(After: workBook.Worksheets.Item[workBook.Worksheets.Count]);
int newSheetRow = 1;
Dictionary<int, string> upData = new Dictionary<int, string>();
for (int sheetIndex = 1; sheetIndex<workBook.Worksheets.Count; sheetIndex++)
{
int rowMax=workBook.Worksheets[sheetIndex].UsedRange.Rows.Count;
int colMax = workBook.Worksheets[sheetIndex].UsedRange.Columns.Count;
for (int i = 0; i < workBook.Worksheets[sheetIndex].UsedRange.Rows.Count; i++)
upData.Add(i, "000000");
for (int row = 1; row < workBook.Worksheets[sheetIndex].UsedRange.Rows.Count; row++)
{
for (int col = 1; col < workBook.Worksheets[sheetIndex].UsedRange.Columns.Count; col++)
{
tempRow = row;
tempCol = col;
if (workBook.Worksheets[sheetIndex].Cells[row, col] != null)
{
Range cell = workBook.Worksheets[sheetIndex].Cells[row, col];
string cellData = cell.Value;
if (cellData != null)
{
string[] datas = cellData.Split(null);
string dataName = null;
for (int k = 1; k < datas.Length; k++)
{
dataName += datas[k];
}
string icd11 = datas[0];
Range newCellData1 = newWorkSheet.Cells[newSheetRow, 1];
newCellData1.Value = icd11;
Range newCellData2 = newWorkSheet.Cells[newSheetRow, 2];
newCellData2.Value = dataName;
Range newCellData3 = newWorkSheet.Cells[newSheetRow, 3];
newCellData3.Value = upData[col - 1];
upData[col] = datas[0];
newSheetRow++;
}
continue;
}
}
}
upData.Clear();
}
}
excel debug is not work in visual studio
I fixed the bugs in my code.
cell. value and these sub-items are not visible
Related
I am trying to transform a datatbale to Excel using this funtion
internal static bool DataTableToExcel(System.Data.DataTable dataTable, string path)
{
_Excel.Application objXL = objXL = new _Excel.Application();
_Excel.Workbook objWB = null;
_Excel.Worksheet ExcelWorkSheet = null;
try
{
objWB = objXL.Workbooks.Add(_Excel.XlWBATemplate.xlWBATWorksheet);
ExcelWorkSheet = objWB.Worksheets[1];
for (int i = 0; i < dataTable.Rows.Count; i++)
{
for (int j = 0; j < dataTable.Columns.Count; j++)
{
ExcelWorkSheet.Cells[i + 1, j + 1] = dataTable.Rows[i][j].ToString();
}
}
objWB.SaveAs(path);
objWB.Close();
objXL.Quit();
return true;
}
catch(Exception ex)
{
objWB.Close();
objXL.Quit();
return false;
}
}
But the final result is missing the header cells in the document: I am only obtaining the date but i need to add the header cells in the excell document too.
In this case I believe you are missing adding the columns names before start the loop in your rows.
Try something like this for sheet's first row:
ExcelWorkSheet.Cells[0,0] = datatable.Columns["columnName"].ColumnName
My Excel has column data like
When I get the data in my asp.net api using below code, I get the data 01-1月-2021 instead of 2021-01-01 then I get the error in line entity.startTime = Convert.ToDateTime(row[0].ToString().Trim());
for (int j = 0; j < HttpContext.Current.Request.Files.Count; j++)
{
string fileName = HttpContext.Current.Request.Files[j].FileName;
if (fileName.Contains(".xlsx") || fileName.Contains(".xls"))
{
dataset = ExcelHelper.ExcelStreamToDataSet(HttpContext.Current.Request.Files[j].InputStream, HttpContext.Current.Request.Files[j].FileName);
bool isFileFind = false;
List<ExcelRowErrorInfoAssetInfo> fileErrorAllList = new List<ExcelRowErrorInfoAssetInfo>();
for (int i = 0; i < dataset.Tables.Count; i++)
{
DataTable table = dataset.Tables[i];
string sheetName = table.TableName;
#region
for (int r = 0; r < table.Rows.Count; r++)
{
DataRow row = table.Rows[r];
int cnt = row.ItemArray.ToList().Where(a => string.IsNullOrEmpty(a.ToString())).Count();
if (cnt < row.ItemArray.Count())
{
if (sheetName == "基本信息")
{
AssetsInfoMap entity = new AssetsInfoMap();
//startTime is type of DateTime
entity.startTime = Convert.ToDateTime(row[0].ToString().Trim());
entity.endTime = Convert.ToDateTime(row[1].ToString().Trim());
}
}
}
#endregion
}
public static DataSet ExcelStreamToDataSet(Stream stream, string fileName)
{
DataSet dataset = new DataSet();
int startRow = 0;
try
{
IWorkbook workbook = null;
if (fileName.IndexOf(".xlsx") > 0)
workbook = new XSSFWorkbook(stream);
else if (fileName.IndexOf(".xls") > 0)
workbook = new HSSFWorkbook(stream);
int sheetCount=workbook.NumberOfSheets;
for (int m = 0; m < sheetCount-1; m++)
{
DataTable data = new DataTable();
ISheet sheet = workbook.GetSheetAt(m);
data.TableName= sheet.SheetName;
if (sheet != null)
{
IRow firstRow = sheet.GetRow(0);
int cellCount = firstRow.LastCellNum;
for (int k = firstRow.FirstCellNum; k < cellCount; ++k)
{
ICell cell = firstRow.GetCell(k);
if (cell != null)
{
string cellValue = cell.StringCellValue;
if (cellValue != null)
{
DataColumn column = new DataColumn(cellValue);
data.Columns.Add(column);
}
}
}
startRow = sheet.FirstRowNum + 1;
int rowCount = sheet.LastRowNum;
for (int i = startRow; i <= rowCount; ++i)
{
IRow row = sheet.GetRow(i);
if (row == null) continue;
DataRow dataRow = data.NewRow();
for (int j = row.FirstCellNum; j < cellCount; ++j)
{
if (row.GetCell(j) != null)
dataRow[j] = row.GetCell(j).ToString();
}
data.Rows.Add(dataRow);
}
}
dataset.Tables.Add(data);
}
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
}
return dataset;
}
}
So how to get correct data to assign it to my model, do you have any ideas based on my above code?
ICell defines a property .DateCellValue, so you should use this when mapping your date values:
ICell cell = row.GetCell(j);
if (cell.CellType == CellType.Numeric && DateUtil.IsCellDateFormatted(cell))
{
dataRow[j] = cell.DateCellValue;
}
This will now store your value as a DateTime rather than as a string. We now need to do away with your DateTime->string->DateTime conversion:
entity.startTime = (DateTime)row[0];
I'm trying to move my numbers(double type) to right side of cell.I take all data from datagridview and put it in my excel table
An excel table includes 5 columns. In the first are strings and the rest of them are numbers of int and double type.
If I have a number with coma in my cell,is the number on the right side,and numbers without coma are on the left side.
I've read I can use something like this one --> myRange.FormatNumber.
But I don't now how I can use this...
try {
string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
saveFileDialog1.InitialDirectory = path;
saveFileDialog1.Title = "Als Excel Datei speichern";
saveFileDialog1.FileName = "";
saveFileDialog1.Filter = "Excel Files(2013)|*.xlsx|Excel Files(2003)|*.xls|Excel Files(2007)|*.xlsx";
if (saveFileDialog1.ShowDialog() != DialogResult.Cancel)
{
Cursor.Current = Cursors.WaitCursor;
Microsoft.Office.Interop.Excel.Application ExcelApp = new Microsoft.Office.Interop.Excel.Application();
ExcelApp.Application.Workbooks.Add(Type.Missing);
object[,] arr = new object[maximaleZeilenAnzahl, maximaleSpaltenAnzahl]; //Array erstellen
//Überschrift Tabelle Einzeln
for (int columnIndex = 0; columnIndex < dgvEinzeln.Columns.Count; columnIndex++)
{
arr[aktuelleExcelZeile, columnIndex] = dgvEinzeln.Columns[columnIndex].HeaderText;
}
aktuelleExcelZeile += 1;
//Tabelle Einzeln
for (int rowIndex = 0; rowIndex < dgvEinzeln.Rows.Count; rowIndex++)
{
for (int columnIndex = 0; columnIndex < dgvEinzeln.Columns.Count; columnIndex++)
{
arr[aktuelleExcelZeile, columnIndex] = dgvEinzeln.Rows[rowIndex].Cells[columnIndex].Value.ToString();
}
aktuelleExcelZeile++;
}
aktuelleExcelZeile += 5;
//Überschrift Tabelle Summe
for (int columnIndex = 0; columnIndex < dgvSumme.Columns.Count; columnIndex++)
{
arr[aktuelleExcelZeile, columnIndex] = dgvSumme.Columns[columnIndex].HeaderText;
}
aktuelleExcelZeile += 1;
//Tabelle Summe
for (int rowIndex = 0; rowIndex < dgvSumme.Rows.Count; rowIndex++)
{
for (int columnIndex = 0; columnIndex < dgvSumme.Columns.Count; columnIndex++)
{
arr[aktuelleExcelZeile, columnIndex] = dgvSumme.Rows[rowIndex].Cells[columnIndex].Value.ToString();
}
aktuelleExcelZeile++;
}
Range c1 = (Range)ExcelApp.Cells[1, 1];
Range c2 = (Range)ExcelApp.Cells[aktuelleExcelZeile, maximaleSpaltenAnzahl];
Range range = ExcelApp.get_Range(c1, c2);
range.Value = arr;
ExcelApp.ActiveWorkbook.SaveCopyAs(saveFileDialog1.FileName.ToString());
ExcelApp.ActiveWorkbook.Saved = true;
ExcelApp.Quit();
string filename = Path.GetFullPath(saveFileDialog1.FileName);
System.Diagnostics.Process.Start(filename);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
throw;
}
finally
{
Cursor.Current = Cursors.Default;
}
Please try this one
ExcelApp.Cells[rownumbwe, columnNumber].HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignRight;
I have just started working with EPPlus. i have data table which has some numeric data and formula. when i load data table by EPPlus and save to excel then formula not evaluated i found when i open the same excel file. formula lies in excel cell as string like SUM(A3:B3)
To evaluate formulate i have tried many options of EPPLUS and those are listed here
pack.Workbook.Worksheets["Test"].Calculate();
pack.Workbook.Worksheets["Test"].Cells["A3"].Calculate();
pack.Workbook.Worksheets["Test"].Cells["B3"].Calculate();
ws.Calculate();
Here i am referring my full sample code where formula not working. please have a look and tell me what i need to add in my code to evaluate formula.
private void button1_Click(object sender, EventArgs e)
{
DataTable dt = GetDataTable();
string path = #"d:\EPPLUS_DT_Excel.xlsx";
Stream stream = File.Create(path);
using (ExcelPackage pack = new ExcelPackage())
{
ExcelWorksheet ws = pack.Workbook.Worksheets.Add("Test");
ws.Cells["A1"].LoadFromDataTable(dt, false);
//pack.Workbook.Worksheets["Test"].Calculate();
//pack.Workbook.Worksheets["Test"].Cells["A3"].Calculate();
//pack.Workbook.Worksheets["Test"].Cells["B3"].Calculate();
ws.Calculate();
pack.SaveAs(stream);
stream.Close();
MessageBox.Show("Done");
}
}
public DataTable GetDataTable()
{
string strSum = "", strColName, strImmediateOneUp = "", strImmediateTwoUp = "";
int startsum = 0;
int currow = 0;
bool firstTimeSum = true;
int NumRows = 3;
int NumColumns = 2;
DataTable dt = new DataTable();
for (int col = 0; col < NumColumns; col++)
{
strColName = GenerateColumnText(col);
DataColumn datacol = new DataColumn(strColName, typeof(object));
dt.Columns.Add(datacol);
}
for (int row = 0; row < NumRows; row++)
{
dt.Rows.Add();
for (int col = 0; col < NumColumns; col++)
{
if (row < 2)
{
dt.Rows[row][col] = Convert.ToInt32(new Random().Next(1, NumRows));
}
else
{
if (firstTimeSum)
{
if (row - currow == 2)
{
currow = row;
startsum = 0;
firstTimeSum = false;
}
else
{
startsum = 1;
}
}
else
{
if (row - currow == 3)
{
currow = row;
startsum = 0;
}
}
if (startsum == 0)
{
strColName = GenerateColumnText(col);
strImmediateOneUp = strColName + ((row + 1) - 1).ToString();
strImmediateTwoUp = strColName + ((row + 1) - 2).ToString();
strSum = string.Format("+SUM({0}:{1})", strImmediateTwoUp, strImmediateOneUp);
dt.Rows[row][col] = strSum;
}
else
{
dt.Rows[row][col] = Convert.ToInt32(new Random().Next(1, NumRows));
}
}
}
startsum = 1;
}
return dt;
}
private string GenerateColumnText(int num)
{
string str = "";
char achar;
int mod;
while (true)
{
mod = (num % 26) + 65;
num = (int)(num / 26);
achar = (char)mod;
str = achar + str;
if (num > 0) num--;
else if (num == 0) break;
}
return str;
}
When adding a formula to a cell you use the Formula property. When you load a range from a DataTable using LoadFromDataTable it has no way of knowing that some of the values are meant to be interpreted as formulas.
You can use LoadDataTable to populate the cells on which the formulas will operate, but for the formulas you'll need to set the Formula property.
I am trying wo write Numbers from a DataTable to an Datasheet - unfortunately, this does not work as expected, e. g. the DataSheet is corrupted.
I am using the following code:
private void AddDataToSheet(ExcelViewData data, SheetData sheetData)
{
var excelData = data.WriteableDataTable;
// this returns a datatable
// the numbers have a format like "8,1" "8,0" etc.
for (int i = 0; i < excelData.Rows.Count; i++)
{
Row row = new Row();
//row.RowIndex = (UInt32)i;
for (int c = 0; c < excelData.Columns.Count; c++)
{
Cell cell = new Cell();
CellValue cellvalue = new CellValue();
//cell.CellReference = SharedMethods.GetExcelColumnName(i + 1) + (c + 1).ToString();
cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.Number;
cellvalue.Text = excelData.Rows[i][c].ToString().Replace(",",".");
cell.Append(cellvalue);
row.Append(cell);
}
sheetData.Append(row);
}
}
Any Idea why this fails? I have seem multiple tutorials with the same approach.
Try out this method:
public void InsertDataTableIntoExcel(SpreadsheetDocument _excelDoc, SheetData SheetData, DataTable excelData, int rowIndex = 1)
{
if (_excelDoc != null && SheetData != null)
{
if (excelData.Rows.Count > 0)
{
try
{
uint lastRowIndex = (uint)rowIndex;
for (int row = 0; row < excelData.Rows.Count; row++)
{
Row dataRow = GetRow(lastRowIndex, true);
for (int col = 0; col < excelData.Columns.Count; col++)
{
Cell cell = GetCell(dataRow, col + 1, lastRowIndex);
string objDataType = excelData.Rows[row][col].GetType().ToString();
//Add text to text cell
if (objDataType.Contains(TypeCode.Int32.ToString()) || objDataType.Contains(TypeCode.Int64.ToString()) || objDataType.Contains(TypeCode.Decimal.ToString()))
{
cell.DataType = new EnumValue<CellValues>(CellValues.Number);
cell.CellValue = new CellValue(objData.ToString());
}
else
{
cell.CellValue = new CellValue(objData.ToString());
cell.DataType = new EnumValue<CellValues>(CellValues.String);
}
}
lastRowIndex++;
}
}
catch (OpenXmlPackageException ex)
{
throw ex;
}
catch (Exception ex)
{
throw ex;
}
}
else
{
OpenXmlPackageException openEx = new OpenXmlPackageException("No data from datatable");
throw openEx;
}
}
else
{
OpenXmlPackageException openEx = new OpenXmlPackageException("Workbook not found");
throw openEx;
}
}