Generating a PDF with two parallel tables - c#

I am attempting to dynamically generate a PDF using iTextSharp with a SQL table of phone book data. My program can currently generate a table with all of the wanted data.
Each page of the PDF only has one long table running down the middle though. I am attempting to format the PDF to have two tables running parallel down the page. When the table reaches the bottom of the page I want the next PdfPRow to be the top of the next table. This is my current C# code to attempt this.
I break up my table into an array of PdfPRows. I then iterate through these adding each row to a new table called section. When the amount of rows have been added that I want I then nest the section table one of two cells on the final table. When I attempt to add this final table to the PDF it throws this error:
iTextSharp.text.DocumentException: Object reference not set to an
instance of an object. at iTextSharp.text.pdf.PdfDocument.Add(IElement
element) at iTextSharp.text.Document.Add(IElement element) at
_Default.Page_Load(Object sender, EventArgs e) in e:\Inetpub\wwwroot\app\cts\phonebook\DefaultPDF.aspx.cs:line 211
I take this to mean that some part of the final table was never initialized but I am not sure. The section after the first for loop is me attempting to fix this error. It is probably not necessary.
Is there is a better way to do this or I am just doing it wrong?

Based on the images provided, this is what I would attempt to do as a start.
First, a couple of knowns.
The data in 2 columns does not exceed 1 page. If it does, this gets more complicated.
Pdf table writes the cells across and then down. With a table of 3 columns, it will write the first 3 cells in the first row and then write the 4th cell in the 2 row
I would set the final table up with 7 colmuns, 6 with data and 1 as a spacer between the 2 data sets. I would then split the rows into 2 arrays. You will need to handle the case of an odd number. Then I would add each row cell by cell, taking the first row from each list to write the first data row of the table.
PdfPTable FinalTableN = new PdfPTable( 7 );
PdfPRow[] n = PDFtableN.Rows.ToArray();
int half = n.Length/2;
PdfPRow[] s1 = new PdfPRow[half];
PdfPRow[] s2 = new PdfPRow[half];
for (int h = 0; h < half; h++ )
s1[h] = n[h];
for ( int h = half; h < n.Length; h++ )
s2[h-half] = n[h];
for ( int h = 0; h < half; h++ ) {
FinalTableN.AddCell( s1[h].GetCells()[0] );
FinalTableN.AddCell( s1[h].GetCells()[1] );
FinalTableN.AddCell( s1[h].GetCells()[2] );
FinalTableN.AddCell( "" );
FinalTableN.AddCell( s2[h].GetCells()[0] );
FinalTableN.AddCell( s2[h].GetCells()[1] );
FinalTableN.AddCell( s2[h].GetCells()[2] );
}
You can control the width of the columns by supplying a float[7] of values to the PdfPTable constructor instead of the the number of columns

Related

Sort for Excel worksheet using C# EPPLUS

I am trying to sort an Excel worksheet using C# EPPLUS. I have reviewed the sort code method here
I am doing this
` var startRow = 11;
var startColumn= 1;
var endRow= 150;
var endColumn= 41;
var sortColumn = 1;
using (ExcelRange excelRange =
yourWorkSheet.Cells[startRow,startColumn, endRow, endColumn])
{
excelRange.Sort(sortColumn, true);
}
`
but that is not working.
The first two columns define what kind of record it is
ex. column one GSMO column 2 is Cost. There are 6 types of record for GSMO
ex GSMO Cost GSMO Profit GSMO LOSS etc.. Then it starts with another value in column 1 such as SESS etc all the way down to the final row
The columns from 3 to 41 are the dollar values associated with the row. So when I sort ascending on column one I want the rest of the columns (2-41) to stay with the same row. I hope this makes sense. Any help would be appreciated Thanks Pene

C# PDF table add row in wrong position

[EDIT due to misunderstanding of the answer]
I'm doing a simple program in C# with PDF file creation with iText7.
In this PDF i'm adding a table whose first cell starts at a certain position in the file.
I don't know if I set the position correctly, but everytime I add another cell with tab.StartNewRow() the resulting new table is repositioned taking THAT last cell as position reference, putting the previously added cells from that point up, while I want to add the cells from that point down.
Which method should I use? That's my code:
Previously I set the position of the first table cell using tab1.SetFixedPosition(20, heigh, width);
and then, in order to add the other cells:
if (mylistbox.Items.Count > 0)
{
tab1.AddCell("FIRST CELL");
tab1.StartNewRow();
for (int i = 0; i < mylistbox.Items.Count; i++)
{
tab1.AddCell(mylistbox.Items[i].ToString());
tab1.StartNewRow();
}
doc.Add(tab1);
}
[EDIT #2] in order to explain my issue better
I have to put 5 tables, which have to grow from a certain point DOWN, positioned at equal distances, same height and width in the doc. This image explains how it should result:
In a WPF application, I have a ListBox with 5 items, numbered 1 through 5. This should be very similar to WinForms.
The CreatePercentArray takes a size which is equal to the amount of columns in a row.
An interesting article about tables: link
private void CreateListBoxTable(Document pdfDoc)
{
// Create an array where each item has an equal width, and use the entire pdf width
// The CreatePercentArray takes a size which is equal to the amount of columns in a row
// By using percentages, they will automatically adapt
// Use CreatePointArray for exacter measurements
var table = new Table(UnitValue.CreatePercentArray(2)).UseAllAvailableWidth();
if (!MyListBox.Items.IsEmpty)
{
foreach (var listBoxItem in MyListBox.Items)
{
table.AddCell(((ListBoxItem) listBoxItem).Content.ToString());
}
}
// Adds table to document
pdfDoc.Add(table);
// Closes document
pdfDoc.Close();
}

Linking the Cells of a spreadsheet like excel to be able to perform formulas c#. Eg: A1 +C8

In Our assignment we were given a task to create a new spreadsheet program with a 26 x 26 grid of textboxes without importing anything and make use of array (in my case I Used array of objects).
I created a 2 d array of objects containing size of grid (27x27). the reason of it being 27 instead of 26 is because the first row and column is to show the ABCDE etc and 12345 etc of the rows and columns.
now the rows indexation I had no problem because it is numeric. however, the letters I solved by creating a string array with alphabet from a to z and entering them through a for loop and it worked.
Now the next step is to be able to link the cells, however, I am a bit stumped, because people told me I have to use Ascii or smthin.
Can anyone help me plz on how to achieve the cell links?
I have been able to past the name of each cell using this code but I fear I just filled the .Text of the cells not the cells name per se:
for (int x = 1; x < TwoDArrayCells.GetLength(0); x++) //nested loop to create the grid of textboxes.
{
for (int y = 1; y < TwoDArrayCells.GetLength(1); y++)
{
Cells CellFields = new Cells(Name = $"{AlphabetRow[x]}{y}", x, y + 3); // called a new cell named CellFields.
CellFields.Text = Name;//Change to location if you wise to take
this.Controls.Add(CellFields);
}
}
The result I would like is to be able to after this be able to link cells. meaning if I insert in a text box A1 + A2 it knows that a1 is the first box in the first row of first column and the a2 is the box in the second row of the first column.
Assuming that Columns can be A-Z only (Capitals), You can extract the column index and row index as follows:
Given a cell, string cell = "A2";
- the column index: int column = cell[0] - 'A' + 1;
- the row index: int row = Convert.ToInt32(cell.Substring(1));
Explanation: for the column, take the first letter, subtract it from 'A' (the subtraction will be performed on the assci codes of the characters) and add 1 since your actual cells are stored starting from index 1. for the row, just parse the rest of the string to int.

Weird issue when removing columns from a datatable

I want to remove every column after the 3rd column from a CSV file loaded into a datatable, but I'm getting odd results. Here's my code.
System.Data.DataTable csv_datatable = null;
using (System.IO.StreamReader re = new System.IO.StreamReader(model.file.InputStream))
{
csv_datatable = CsvParser.Parse(re as System.IO.TextReader);
for (int x = 3; x < csv_datatable.Columns.Count + 1; x++)
{
csv_datatable.Columns.RemoveAt(x);
}
}
My sample CSV file:
7 columns, and I want to keep the first three.
email,first,last,middle,nick,job,phone
roryok#fakedomain.com,rory,wally,ok,danger,developer,555-0123
This is the result I get.
email,first,last,nick,phone
roryok#fakedomain.com,rory,ok,danger,555-0123
As you can see, rather than removing the last columns as I would expect, the code actually removes the 4th and 6th columns.
As usual, figured this out as I was posting, but I'll post the solution anyway in case it helps someone.
As each column is removed, the index for each column changes. So when you remove column 3, 4 becomes the new 3. This code works:
for (int x = 0; x < csv_datatable.Columns.Count; x++)
{
csv_datatable.Columns.RemoveAt(3);
}
This will loop over the number of columns, and remove the third column over and over again until everything is gone.

Insert a single record from a text file into 3 tables

I have a generated text file with 70 lines. It's a web form from one of my partner "legacy" platform and this is sent to me by email, on a text file :
Name
First Name
First Name + Name
Age
Telephone
City
Country
Email
Website
Profession
Etc
Etc 2
...
I want to "split" this text file into 3 records in my MS-SQL database using C# and ASP.NET.
The 3 tables are something like this :
Client_General_Information
Client_Private_Information
Client_Request_Problem
And I want to target specific lines, for specific tables and fields. Example :
Line 1 goes in Table 1 (Name field)
Line 2 goes in Table 1 (First name field)
Line 3 goes in Table 1 (...)
Line 4-5-6 goes in Table 3 ( 3 other fields)
Line 7-9 goes in Table 1 (2 other fields)
Line 10 goes in Table 2 (...)
I am searching a way to read the text file, and insert into the values into 3 tables. The text file will always have the same number of lines and will always have same order. Sometimes lines are empty but it is changing from file to file.
So I have my file reader, but I am not sure where to go next :
//Load our text file
TextReader tr = new StreamReader("\\test.txt");
int NumberOfLines = 70;
//Make our array for each line
string[] ListLines = new string[NumberOfLines];
//Read the number of lines and put them in the array
for (int i = 0; i < NumberOfLines; i++)
{
ListLines[i] = tr.ReadLine();
}
//
tr.Close();
Should I make 3 arrays or 3 lists and insert each one of them ? Just to be clear, I dont want to "bulk insert". Each text file is a unique client !
Thanks
Create a separate class having the getter and setter methods same as the fields in the 3 tables
Client_General_Information
Client_Private_Information
Client_Request_Problem
Then read from the file and assign values to respective fields in the objects like
...
Client_General_Information newObject = new Client_General_Information ();
int NumberOfLines = 70;
//Make our array for each line
string[] ListLines = new string[NumberOfLines];
//Read the number of lines and put them in the array
for (int i = 0; i < NumberOfLines; i++)
{
ListLines[i] = tr.ReadLine();
}
newObject.Name=ListLines[0];
newObject.LastName=ListLines[1];
and so on then insert the data in the database as per your requirement from the objects.

Categories