Break datatable into multiple tables by columns not rows - c#

I have a datatable having columns like below
I want to break datatable into multiple datatables by splitting columns with every group of 4 columns like below
I can do it by simply by using loops and some calculations but wanted to get a better way if someone have.

DataTable has a copy method, you could use that, and remove the columns you don't need.
https://msdn.microsoft.com/en-us/library/system.data.datatable.copy(v=vs.110).aspx
System.Data.DataTable tbl = new System.Data.DataTable();
// Add Dummy Columns
for (int i = 0; i <= 11; i++)
{
tbl.Columns.Add(i.ToString());
}
// Assume We Have Data
// Split Table Into Lists of Tables
List <System.Data.DataTable> tables = new List<System.Data.DataTable>();
for ( int i = 0; i <= 2; i++)
{
int firstColumn = i * 4;
int lastColumn = i * 4 + 3;
System.Data.DataTable tblCopy = tbl.Copy();
for ( int j = 0; j < tbl.Columns.Count; j++)
{
if (j < firstColumn || j > lastColumn)
tblCopy.Columns.Remove(tbl.Columns[j].ColumnName);
}
tables.Add(tblCopy);
}

Related

List<List<string>> into ASP Table

I'm trying to input the data in my list of list of strings as rows in a ASP table element. All the correct data is passed through, but the rows repeat themselves by 3 times. How do add to the table element only once?
List<List<string>> table = NorthwindAccess.GetProducts(ddl_Supplier.SelectedItem.Value);
for (int i = 0; i < table.Count(); ++i)
{
for (int k = 1; k < table[i].Count(); ++k)
{
row1 = new TableRow(); //create as many rows as in each column (name, quantity, stock)
for (int j = 0; j < table.Count(); ++j)
{
string cellData = table[j][k];
TableCell cells = new TableCell();
cells.Text = cellData;
row1.Cells.Add(cells);
}
ProductsTable.Rows.Add(row1);
}
}

How to merge first 3 columns for rows with same value in PDF

I'm using itextSharp to export a DataTable to a pdf table. I can export the data to a pdf table using the sample code i have posted below. The DataTable contains close to 21 columns.
The first column in the pdf (DataTable) might contain similar values for any number of rows. If the data values in first column for a group of rows is similar, i want to merge the first 3 columns of those rows as one cell.
I'm having trouble modifying the code below to achieve this.
public iTextSharp.text.Table GetItextTable(DataTable dtChartData, string reportType)
{
int intCols = dtChartData.Columns.Count; //Total number of columns
int intRows = dtChartData.Rows.Count; //Total number of rows
iTextSharp.text.Table pdfTable = new iTextSharp.text.Table(intCols, intRows);
try
{
pdfTable.BorderWidth = 1;
pdfTable.Width = 100;
pdfTable.Padding = 1;
pdfTable.Spacing = 1;
/*creating table headers */
for (int i = 0; i < intCols; i++)
{
iTextSharp.text.Cell cellCols = new iTextSharp.text.Cell();
iTextSharp.text.Font ColFont = iTextSharp.text.FontFactory.GetFont("Tahoma", 07,
iTextSharp.text.Font.BOLD);
for (int l = 0; l < dtChartData.Columns.Count; l++)
{
if (dtChartData.Columns[l].ColumnName.Contains("_"))
{
dtChartData.Columns[l].ColumnName = dtChartData.Columns[l].ColumnName.Replace("_", " ");
}
}
iTextSharp.text.Chunk chunkCols = new iTextSharp.text.Chunk(dtChartData.Columns[i].ColumnName,ColFont);
cellCols.HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER;
if ((chunkCols.ToString().ToLower() == "ReportDetails"))
{
cellCols.HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER;
}
}
/* loop that take values from every row in datatable and insert in itextsharp table */
for (int k = 0; k < intRows; k++)
{
for (int j = 0; j < intCols; j++)
{
iTextSharp.text.Cell cellRows = new iTextSharp.text.Cell();
iTextSharp.text.Font RowFont = iTextSharp.text.FontFactory.GetFont("Tahoma", 07);
iTextSharp.text.Chunk chunkRows = new iTextSharp.text.Chunk(dtChartData.Rows[k][j].ToString(),RowFont);
cellRows.HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER;
cellRows.Add(chunkRows);
pdfTable.AddCell(cellRows);
}
}
}
catch (Exception ex)
{
//error handling code here removed
}
return pdfTable;
}
Have you tried to change the Colspan?
iTextSharp.text.Cell cell = new iTextSharp.text.Cell();
cell.AddElement(new Paragraph("colspan 3"));
cell.Colspan = 3;
table.AddCell(cell);
In this case, cell will span three columns.
try this. i just edited your code, not checked
here i have edited 1 line of your code and added a new line (total 2 lines of change only).
dont forget to combine headding row like this, if you need
/* loop that take values from every row in datatable and insert in itextsharp table */
for (int k = 0; k < intRows; k++)
{
for (int j = 2; j < intCols; j++)// EDIT: if all first 3 cols are same, then starts with 2
{
iTextSharp.text.Cell cellRows = new iTextSharp.text.Cell();
if(j == 2) cellRows.Colspan = 3;// ADD: it'll gives a 3 times long cell
iTextSharp.text.Font RowFont = iTextSharp.text.FontFactory.GetFont("Tahoma", 07);
iTextSharp.text.Chunk chunkRows = new iTextSharp.text.Chunk(dtChartData.Rows[k][j].ToString(),RowFont);
cellRows.HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER;
cellRows.Add(chunkRows);
pdfTable.AddCell(cellRows);
}
}

Is it possible to copy row (with data, merging, style) in Excel using Epplus?

The problem is that I need to insert data into Excel from the collection several times using a single template for the entire collection.
using (var pckg = new ExcelPackage(new FileInfo(association.TemplatePath)))
{
var workSheet = pckg.Workbook.Worksheets[1];
var dataTable = WorksheetToDataTable(workSheet);
/*Some stuff*/
FindAndReplaceValue(workSheet, dictionary, row);
}
private DataTable WorksheetToDataTable(ExcelWorksheet oSheet)
{
int totalRows = oSheet.Dimension.End.Row;
int totalCols = oSheet.Dimension.End.Column;
DataTable dt = new DataTable(oSheet.Name);
DataRow dr = null;
for (int i = 1; i <= totalRows; i++)
{
if (i > 1) dr = dt.Rows.Add();
for (int j = 1; j <= totalCols; j++)
{
if (i == 1)
dt.Columns.Add((oSheet.Cells[i, j].Value ?? "").ToString());
else
dr[j - 1] = (oSheet.Cells[i, j].Value ?? "").ToString();
}
}
return dt;
}
First picture - My template. Second - First element of collection (with data, style, merging). Third - Other elements has only data
I just made copies of rows
for (int i = 0; i < invoiceList.Count; i++)
{
workSheet.Cells[1, 1, totalRows, totalCols].Copy(workSheet.Cells[i * totalRows + 1, 1]);
}
If you want to copy range just use :
workSheet.Cells["A1:I1"].Copy(workSheet.Cells["A4:I4"]);

Transposing columns in GridView

I have a data table that contains the data like below.
I want to display it in my Grid View like Following. It is actually the transpose of above table and one additional Row added for Viewing Product Details that will be a link button.
Can you please help me how can I achieve the following requirement in ASP.net using C#.
Many Thanks,
Awais Afzal.
Assuming that you table is a DataTable, you could use such an extension to reorder it:
public static DataTable Pivot(this DataTable tbl)
{
var tblPivot = new DataTable();
tblPivot.Columns.Add(tbl.Columns[0].ColumnName);
for (int i = 1; i < tbl.Rows.Count; i++)
{
tblPivot.Columns.Add(Convert.ToString(i));
}
for (int col = 0; col < tbl.Columns.Count; col++)
{
var r = tblPivot.NewRow();
r[0] = tbl.Columns[col].ToString();
for (int j = 1; j < tbl.Rows.Count; j++)
r[j] = tbl.Rows[j][col];
tblPivot.Rows.Add(r);
}
return tblPivot;
}
and set it as new DataSource:
dataGridView1.DataSource = oldDataTable.Pivot();

Simplest way of programmatically creating a DataGridView with X columns by Y rows

In C# Winforms, I'd like to use a DataGridView as a simple widget to store information to display to the user. To this end, I'd like to create a table of say, 5x10 cells.
After some research, solutions tend to allow adding just one row or column at a time. I'd like the whole grid created initially and straight away, so I can start populating it with data, like you would with a standard C# 2D array.
What's the simplest way of going about this? A function header could look like this:
createCells(DataGridView dgv, int cols, int rows) {}
It should be quick and amenable to changing the cols and rows to a larger or smaller number later on if need be.
By the way, there might an error like:
Sum Of The Columns' FillWeight Values Cannot Exceed 65535
To avoid it, set AutoGenerateColumns property to false, and set FillWeight to 1 for each column generated:
dgv.AutoGenerateColumns = false;
for (int i = 1; i <= columns; i++)
{
dgv.Columns.Add("col" + i, "column " + i);
dgv.Columns[i - 1].FillWeight = 1;
}
for (int j = 0; j < rows; j++)
dgv.Rows.Add();
You can do by using for loops in this way:
private DataGridView DGV_Creation(DataGridView dgv, int columns, int rows)
{
for (int i = 1; i <= columns; i++)
{
dgv.Columns.Add("col" + i, "column " + i);
}
for (int j = 0; j < rows; j++)
{
dgv.Rows.Add();
}
return dgv;
}
Call it with:
this.dataGridView1 = DGV_Creation(dataGridView1, 5, 10); // 5 columns, 10 rows (empty rows)
or:
private void DGV_Creation(ref DataGridView dgv, int columns, int rows)
{
for (int i = 1; i <= columns; i++)
dgv.Columns.Add("col" + i, "column " + i);
for (int j = 0; j < rows; j++)
dgv.Rows.Add();
}
call it with:
DGV_Creation(ref this.dataGridView1, 5, 10); //5 columns, 10 rows (empty rows)

Categories

Resources