How can I use NPOI to insert a row like excel?
The excel insert command copy the format for the upper row
Thanks!
static void InsertRows(ref HSSFSheet sheet1, int fromRowIndex, int rowCount)
{
sheet1.ShiftRows(fromRowIndex, sheet1.LastRowNum, rowCount, true, false, true);
for (int rowIndex = fromRowIndex; rowIndex < fromRowIndex + rowCount; rowIndex++)
{
HSSFRow rowSource = sheet1.GetRow(rowIndex + rowCount);
HSSFRow rowInsert = sheet1.CreateRow(rowIndex);
rowInsert.Height = rowSource.Height;
for (int colIndex = 0; colIndex < rowSource.LastCellNum; colIndex++)
{
HSSFCell cellSource = rowSource.GetCell(colIndex);
HSSFCell cellInsert = rowInsert.CreateCell(colIndex);
if (cellSource != null)
{
cellInsert.CellStyle = cellSource.CellStyle;
}
}
}
}
maybe you can look here for some inspiration
HSSFRow newRow = worksheet.GetRow(destinationRowNum);
HSSFRow sourceRow = worksheet.GetRow(sourceRowNum);
// If the row exist in destination, push down all rows by 1 else create a new row
if (newRow != null)
{
worksheet.ShiftRows(destinationRowNum, worksheet.LastRowNum, 1);
}
else
{
newRow = worksheet.CreateRow(destinationRowNum);
}
I am using this code to create a new row. This might come handy to you.
Related
I have a Janus Grid with a checkbox in each row and wanna copy selected row(s) to a DataRowCollection or to DataRow[] .this is my way but not completed and not worked:
also this grid has group on one field and I use 2 loop for group and childs.
gridEX1.DataSource = dtALL;//dtALL is a data table fill with select sql command
DataRowCollection dr
DataRow dr2=dtALL.NewRow();
foreach (Janus.Windows.GridEX.GridEXRow g in gridEX1.GetRows())
{
foreach (Janus.Windows.GridEX.GridEXRow r in g.GetChildRows())
{
if ((bool)r.Cells["sendALL"].Value == true && r.Cells["DocTitle"].Value.ToString() == DocTitle)
{
for(int i=0;i<r.Cells.Count;i++)
if(r.Cells[i].GetType()==typeof(TextBox))
{
dr2[i] = r.Cells[i].Value;
}
dr.Add(dr2);
}
}
}
I figured out this way and solved my problem:
DataTable dt1copy = new DataTable();
dt1copy.Columns.Add("DocTitle");
dt1copy.Columns.Add("DocDetails");
dt1copy.Columns.Add("ExpLenght");
dt1copy.Columns.Add("ReqDate");
dt1copy.Columns.Add("ReqTypeDetailsTitle");
dt1copy.Columns.Add("ReqTypeTitle");
dt1copy.Columns.Add("UnitsTitle");
dt1copy.Columns.Add("DocType");
dt1copy.Columns.Add("DocSuffix");
dt1copy.Columns.Add("FKGID");
dt1copy.Columns.Add("Id");//id of docinreq tbl
DataRow dr2;
DataRowCollection dr = dt1copy.Rows;
string DocTitle = gridEX1.CurrentRow.Cells["DocTitle"].Value.ToString();
foreach (Janus.Windows.GridEX.GridEXRow g in gridEX1.GetRows())
{
foreach (Janus.Windows.GridEX.GridEXRow r in g.GetChildRows())
{
try
{
if ((bool)r.Cells["sendALL"].Value == true && r.Cells["DocTitle"].Value.ToString() == DocTitle)
{
dr2 = dt1copy.NewRow();
for (int i = 0, j = 0; i < r.Cells.Count; i++)
{
if (r.Cells[i].Column.BoundMode != Janus.Windows.GridEX.ColumnBoundMode.UnboundFetch)//select only bounded column from grid
{
dr2[j] = r.Cells[i].Value.ToString();
j++;
}
}
dt1copy.Rows.Add(dr2);
}
}
catch (Exception) { }
}
}
dr = dt1copy.Rows;
Using C#, which is the best and easiest way to export all the data from a datatable to an excel to get it downloaded?
I use Microsoft Interop.
Here is some sample code to get you started.
There are probably hundreds of tutorials which are better than the below. I have removed much of the code I use so I doubt the following will compile, but with careful reading, and some investigation into tutorials, you should be able to accomplish what you need.
public static void ExportToExcel(DataSet dsTodo, string strPathToSaveFile)
{
try
{
int numSteps = (dsTodo != null ? dsTodo.Tables.Count * 2 : 1);
Microsoft.Office.Interop.Excel.ApplicationClass ExcelApp = new Microsoft.Office.Interop.Excel.ApplicationClass();
Workbook xlWorkbook = ExcelApp.Workbooks.Add(Microsoft.Office.Interop.Excel.XlWBATemplate.xlWBATWorksheet);
if (dsTodo.Tables.Count > 0)
{
for (int i = dsTodo.Tables.Count; i > 0; i--)
{
Sheets xlSheets = null;
Worksheet xlWorksheet = null;
//Create Excel Sheets
xlSheets = ExcelApp.Sheets;
xlWorksheet = (Worksheet)xlSheets.Add(xlSheets[1], Type.Missing, Type.Missing, Type.Missing);
System.Data.DataTable table = dsTodo.Tables[i - 1];
xlWorksheet.Name = table.TableName;
for (int j = 1; j < table.Columns.Count + 1; j++)
{
ExcelApp.Cells[1, j] = table.Columns[j - 1].ColumnName;
}
var excelData = new object[table.Rows.Count, table.Columns.Count];
for (int rowJ = 0; rowJ < table.Rows.Count; rowJ++)
{
for (int colI = 0; colI < table.Columns.Count; colI++)
{
excelData[rowJ, colI] = table.Rows[rowJ][colI];
}
}
int startCol = 1;
int endCol = startCol + table.Columns.Count - 1;
int startRow = 2;
int endRow = startRow + table.Rows.Count - 1;
string startLoc = GetCellFromCoords(startCol, startRow);
string endLoc = GetCellFromCoords(endCol, endRow);
//ExcelApp.get_Range(startLoc, endLoc).Value2 = excelData;
try
{
Range valRange = ExcelApp.get_Range(startLoc, endLoc);
valRange.Value2 = excelData;
}
I have a DataTable which has the following structure.
StartDate (Type DateTime)
EndDate (Type DateTime)
Description (Type Text)
What I need to check is if the dates overlap or not, i.e., if the Start Date of 1 item is less than the EndDate of the previous item.
Here is the code I wrote.
NB: I already have checks to ensure that for each record, the Start Date has to be lesser than the End Date
dtDates.DefaultView.Sort = "StartDate ASC"; //Sort the DataTable based on the Start Dates
if(dtDates.Rows.Count > 1) //Check only if more than 1 Date is specified
{
for (int i = 1; i < dtDates.Rows.Count; i++)
{
if(TypeConvert.ToDate(dtDates.Rows[i]["StartDate"] < TypeConvert.ToDate(dtDates.Rows[i-1]["EndDate"])
{
retVal = true;
currentRow = i;
break;
}
}
}
The above code works fine.
But now, I want to implement it using LINQ
So, here is the code I am trying to attempt.
How can I do the whole comparison using LINQ?
public static bool CheckIfDatesOverlap(DataTable dataTable)
{
bool retVal = false;
int currentRow = 0;
List<DataRow> listDates = (from DataRow dgv in dataTable.Rows
select dgv).OrderBy(x => x[StartDate]).ToList();
if (listDates.Count > 1) //Perform Comparision only if more than 1 row is present
{
for (int i = 1; i < listDates.Count; i++)
{
if (TypeConvert.ToDateTime(listDates[i][StartDate]) < TypeConvert.ToDateTime(listDates[i][EndDate]))
{
retVal = true; //There are duplicates, hence return true
currentRow = i;
break;
}
else
{
//Do nothing as dates do not overlap
}
}
}
else
{
retVal = false; //As there is only 1 row, return false
}
if (retVal)
{
string message = "Dates Overlap";
//Display message
}
return retVal;
}
If you use SelectWithPrevious described here then you can write the following:
bool datesOverlap = table.Rows
.Cast<DataRow>()
.SelectWithPrevious((current, previous) => new
{
PreviousEndDate = (DateTime)previous["EndDate"],
StartDate = (DateTime)current["StartDate"]
})
.Any(x => x.StartDate < x.PreviousEndDate);
I have created a JTable, the table contains 4 rows, and for a specific row, I have overridden the sorting and its working fine only on that column.
Status Scheduled Date Scheduled time Status
false 30/01/2012 02:00:00 Scheduled
false 29/01/2012 14:58:00 Scheduled
false 29/01/2012 15:50:00 Scheduled
For Scheduled Date, which I try to sort, it would sort, but the respecitve rows are not being updated.
Here is my code for sorting
public static void sortColumn(DefaultTableModel model, int colIndex,
boolean sortingOrder) {
Vector<?> data = model.getDataVector();
Object[] colData = new Object[model.getRowCount()];
SortedSet<Object> dataCollected = null;
List<Date> dateCollected;
boolean dateFlag = false;
dateCollected = new ArrayList<Date>();
// Copy the column data in an array
for (int i = 0; i < colData.length; i++) {
Object tempData = ((Vector<?>) data.get(i)).get(colIndex);
if ((colIndex == 1 || colIndex == 4)
&& tempData.toString().contains("/")) {
String[] _scheduledDate1 = ((String) tempData).split("/");
Calendar _cal1 = Calendar.getInstance();
_cal1.set(Integer.parseInt(_scheduledDate1[2]),
Integer.parseInt(_scheduledDate1[1]) - 1,
Integer.parseInt(_scheduledDate1[0]));
dateCollected.add(_cal1.getTime());
dateFlag = true;
} else {
colData[i] = ((Vector<?>) data.get(i)).get(colIndex);
}
}
// DateCompare compare = new DateCompare();
if (!dateFlag) {
dataCollected = new TreeSet<Object>();
dataCollected.add(colData);
dateFlag = false;
}
// Copy the sorted values back into the table model
if ((colIndex == 1 || colIndex == 4) && dateFlag) {
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
sortOrder = !sortOrder;
if (sortOrder) {
Collections.sort(dateCollected);
} else {
Collections.sort(dateCollected, Collections.reverseOrder());
}
colData = dateCollected.toArray();
for (int i = 0; i < colData.length; i++) {
((Vector<Object>) data.get(i)).set(colIndex,
sdf.format(((Date) colData[i]).getTime()));
}
} else {
for (int i = 0; i < colData.length; i++) {
((Vector<Object>) data.get(i)).set(colIndex, colData[i]);
}
}
model.fireTableStructureChanged();
}
How to I get the entire row update accordingly?
I found the problem, my object against I was comparing was wrong, I've change the code for the same it all works fine.
I implemented QuickSort algorithm to sort the vector on the specific column I need.
I´m exporting datatables to Excel workbook. Problem is that the datatable holds 90000 rows and excel can only hold 67000 rows in every sheet.
So..
How can i divide one big datatable to two datatables, maybe with Linq ?
Then i can have datatable1 in sheet1 and datatable2 in sheet2
Sincerly
agh
Assuming that you're getting the 90,000 rows for this DataTable from a database somewhere, the most efficient approach would be to modify your SELECT statement into two new SELECT statements, each of which returns < 67,000 rows, and then do everything else the same.
Split your recordset. Perform one SELECT that extracts all 90,000 rows, and split it on Excel import step.
private List<DataTable> CloneTable(DataTable tableToClone, int countLimit)//Split function
{
List<DataTable> tables = new List<DataTable>();
int count = 0;
DataTable copyTable = null;
foreach (DataRow dr in tableToClone.Rows)
{
if ((count++ % countLimit) == 0)
{
copyTable = new DataTable();
copyTable = tableToClone.Clone();
copyTable.TableName = "Sample" + count;
tables.Add(copyTable);
}
copyTable.ImportRow(dr);
}
return tables;
}
protected void LinkReport_Click(object sender, EventArgs e)
{
DataTable dt2 = (DataTable)ViewState["dtab"];
List<DataTable> dt1 = CloneTable(dt2, 5);
DataSet ds = new DataSet("dst");
for (int i = 0; i < dt1.Count; i++)
{
ds.Tables.Add(dt1[i]);
}
string filePath = Server.MapPath("Reports/").ToString() + "master.xls";
FileInfo file = new FileInfo(filePath);
if (file.Exists)
{
file.Delete();
}
Export(ds, filePath);// Export into Excel
}
Clone - The fastest method to create tables with original columns structure is Clone method.
Export into Excel
private void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
}
finally
{
GC.Collect();
}
}
public void Export(DataSet ds, string filePath)
{
string data = null;
string columnName = null;
int i = 0;
int j = 0;
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
//Excel.Worksheet xlWorkSheet;
Excel.Worksheet xlWorkSheet = null;
object misValue = System.Reflection.Missing.Value;
Excel.Range range;
xlApp = new Excel.ApplicationClass();
xlWorkBook = xlApp.Workbooks.Add(misValue);
//xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
for (int l = 0; l < ds.Tables.Count; l++)
{
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(l + 1);
xlWorkSheet.Cells[1, 1] = "Report";
xlWorkSheet.get_Range("A1:D1", Type.Missing).Merge(Type.Missing);
xlWorkSheet.get_Range("A1", "D1").Font.Bold = true;
xlWorkSheet.Cells.Font.Name = "Courier New";
if (l == 0)
{
xlWorkSheet.Name = "Sheet1";
}
else if (l == 1)
{
xlWorkSheet.Name = "Sheet2";
}
else if (l == 2)
{
xlWorkSheet.Name = "Sheet3";
}
else if (l == 3)
{
xlWorkSheet.Name = "Sheet4";
}
else if (l == 4)
{
xlWorkSheet.Name = "Sheet5";
}
for (i = 0; i <= ds.Tables[l].Rows.Count - 1; i++)
{
for (j = 0; j <= ds.Tables[l].Columns.Count - 1; j++)
{
columnName = ds.Tables[l].Columns[j].ColumnName.ToString();
xlWorkSheet.Cells[3, j + 1] = columnName;
data = ds.Tables[l].Rows[i].ItemArray[j].ToString();
xlWorkSheet.Cells[i + 5, j + 1] = data;
}
}
}
//for (i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
//{
// for (j = 0; j <= ds.Tables[0].Columns.Count - 1; j++)
// {
// data = ds.Tables[0].Rows[i].ItemArray[j].ToString();
// xlWorkSheet1.Cells[i + 1, j + 1] = data;
// }
//}
xlWorkBook.SaveAs(filePath, Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
// kill all excel processes
Process[] pros = Process.GetProcesses();
for (int p = 0; p < pros.Length; p++)
{
if (pros[p].ProcessName.ToLower().Contains("excel"))
{
pros[p].Kill();
break;
}
}
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp);
}
Try this One.. I have Worked out in Visual Studio 2005
DataTable[] splittedtables = dt.AsEnumerable()
.Select((row, index) => new { row, index })
.GroupBy(x => x.index / Input From User) // integer division, the fractional part is truncated
.Select(g => g.Select(x => x.row).CopyToDataTable())
.ToArray();
This should work.