inserting list data into table in itext7 pdf (xamarin android) - pdf

I have a list and I need to put the data of this list in a pdf file. I searched and found the itext7 library where you can create a table in the pdf. I wrote the following code:
var path2 = global::Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
filePath = Path.Combine(path2.ToString(), "Client's_Account.pdf");
stream = new FileStream(filePath, FileMode.Create);
PdfWriter writer = new PdfWriter(stream);
PdfDocument pdf2 = new iText.Kernel.Pdf.PdfDocument(writer);
Document document = new Document(pdf2,iText.Kernel.Geom.PageSize.TABLOID);
Paragraph header;
acc_info acc = new acc_info();
//foreach (var t in tableItems)
//{
// string txt = t.itembarcode + " " + t.itemsunitcode + " " + t.name + "\n";
// header = new Paragraph(txt);
// document.Add(header);
//}
iText.Layout.Element.Table table = new iText.Layout.Element.Table(5, false);
// table.SetWidth(400).SetFixedLayout();
table.AddCell(new Cell(1, 1).SetTextAlignment(iText.Layout.Properties.TextAlignment.CENTER).Add(new Paragraph("Date")));
table.AddCell(new Cell(1, 2).SetTextAlignment(iText.Layout.Properties.TextAlignment.CENTER).Add(new Paragraph("Reference")));
table.AddCell(new Cell(1, 3).SetTextAlignment(iText.Layout.Properties.TextAlignment.CENTER).Add(new Paragraph("Description")));
table.AddCell(new Cell(1, 4).SetTextAlignment(iText.Layout.Properties.TextAlignment.CENTER).Add(new Paragraph("Debit")));
table.AddCell(new Cell(1, 5).SetTextAlignment(iText.Layout.Properties.TextAlignment.CENTER).Add(new Paragraph("Credit")));
for (int i = 0; i < user.tableItems_accInfo.Count; i++)
{
int j = 0;
table.AddCell(new Cell(i + 2, j + 1).SetTextAlignment(iText.Layout.Properties.TextAlignment.CENTER).Add(new Paragraph(user.tableItems_accInfo[i].jvdate)));
j = j + 1;
table.AddCell(new Cell(i + 2, j + 1).SetTextAlignment(iText.Layout.Properties.TextAlignment.CENTER).Add(new Paragraph(user.tableItems_accInfo[i].jvref)));
j = j + 1;
table.AddCell(new Cell(i + 2, j + 1).SetTextAlignment(iText.Layout.Properties.TextAlignment.CENTER).Add(new Paragraph(user.tableItems_accInfo[i].desc)));
j = j + 1;
table.AddCell(new Cell(i + 2, j + 1).SetTextAlignment(iText.Layout.Properties.TextAlignment.CENTER).Add(new Paragraph(user.tableItems_accInfo[i].jvdebit)));
j = j + 1;
table.AddCell(new Cell(i + 2, j + 1).SetTextAlignment(iText.Layout.Properties.TextAlignment.CENTER).Add(new Paragraph(user.tableItems_accInfo[i].jvcredit)));
}
document.Add(table);
string txt = "\n \n Total Credit= " + tot_crdt.Text +"\n \n Total Debit= "+tot_dbt.Text+ "\n \n Total Balance= "+balance.Text;
header = new Paragraph(txt);
document.Add(header);
document.Close();
Toast.MakeText(this.Context, "PDF Generated", ToastLength.Short).Show();
but the table I get is so bad even if I change the pdf pagesize (A4, legal, tabloid...). what did I do wrong?
here's the table that I get:
thanks in advance

You seem to misinterpret the Cell constructor parameters. They don't represent the row and column in which the cell shall go but instead the number of rows and columns the cell shall span.
Instead of
new Cell(n, m)
for various n and m, therefore, you should use
new Cell()

Related

Clear Previous selection of Dropdown in EXCEL usingApache POI

I have developed the excel using the Apache NPOI dll using HSSFWORKBOOK. But in my excel having 3 dependent dropdowns one in each other.
Here my question is I am unable to clear the cell value of dependent dropdowns. Let say like dropdown1 have country values and on the selection of this dropdown2 state values got a filter and selected one of the state. Now if I changed the country again able to filter the data but whatever the previous state selection not getting cleared.
code ref:
No, i am just referring the list of columns data from sheet2 to sheet1 using the formulae. below is code ref:
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
//if (i >= MaxRowCount)
//{
// sheet2.CreateRow(1000 + i).CreateCell(1).SetCellValue(ds.Tables[0].Rows[i][1].ToString());
// MaxRowCount += 1;
//}
//else
// sheet2.GetRow(1000 + i).CreateCell(1).SetCellValue(ds.Tables[0].Rows[i][1].ToString());
if (CategoryCount == 250)
{
rownumber = rownumber + 3000;
CategoryCount = 16;
MaxRowCount = 0;
}
DataRow[] DR = ds.Tables[1].Select("LOCATION_ID=" + ds.Tables[0].Rows[i][0].ToString());
int RowCount = 0;
//int rownumber = 1000;
foreach (DataRow d in DR)
{
if (RowCount >= MaxRowCount)
{
sheet2.CreateRow(rownumber + RowCount).CreateCell(CategoryCount).SetCellValue(d[0].ToString());
MaxRowCount += 1;
}
else
{
sheet2.GetRow(rownumber + RowCount).CreateCell(CategoryCount).SetCellValue(d[0].ToString());
}
RowCount++;
}
IName DeptHierarchy_Dept = hssfworkbook.CreateName();
DeptHierarchy_Dept.NameName = "XDeptHierarchy_Dept_SUB" + (XDeptHierarchy_Dept_SUBCount).ToString();
if (CategoryCount / 26 < 1)
DeptHierarchy_Dept.RefersToFormula = "'Template Field Specs2'!$" + ((char)(65 + CategoryCount)).ToString() + "$" + (StartRowNumber + 1) + ":$" + ((char)(65 + CategoryCount)).ToString() + "$" + ((StartRowNumber + 1) + (RowCount == 0 ? 0 : RowCount - 1)).ToString();
else
DeptHierarchy_Dept.RefersToFormula = "'Template Field Specs2'!$" + ((char)(65 + (CategoryCount / 26) - 1)).ToString() + ((char)(65 + CategoryCount % 26)).ToString() + "$" + (StartRowNumber + 1) + ":$" + ((char)(65 + (CategoryCount / 26) - 1)).ToString() + ((char)(65 + CategoryCount % 26)).ToString() + "$" + ((StartRowNumber + 1) + (RowCount == 0 ? 0 : RowCount - 1)).ToString();
CategoryCount++;
XDeptHierarchy_Dept_SUBCount++;
You are looking for "Dependent Drop Down Lists". You'll have to be creative for your formula because your row will keep changing.
one approach i can think of is store the list of "Country-capital" on named region some where deep in excel. On selection of country, parse and find the capital from named region and populate your target cell.
Please see the documentation.
Also this link;

How to break pdf page in itextsharp pdf

I have written the following code to generate pdf:
path = Server.MapPath("PDF-Files")
filename = path + "/mydata.pdf"
document = New iTextSharp.text.Document(iTextSharp.text.PageSize.A4, 5.0F, 5.0F, 5.0F, 5.0F)
Dim bfTimes As BaseFont
Dim times As iTextSharp.text.Font
bfTimes = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1252, False)
times = New iTextSharp.text.Font(bfTimes, 8, iTextSharp.text.Font.NORMAL)
Dim writer As PdfWriter
writer = PdfWriter.GetInstance(document, New FileStream(filename, FileMode.Create))
Dim ev As New itsEvents
writer.PageEvent = ev
If document.IsOpen Then
document.Close()
End If
document.Open()
Dim spacing As Integer
spacing = 0
Dim curY, lineHeight As Double
curY = document.Top
lineHeight = 0
Const maxPerLine As Integer = 3
For k As Integer = 0 To ds.Tables(0).Rows.Count - 1
Dim table As PdfPTable
table = New PdfPTable(3)
table.DefaultCell.Border = iTextSharp.text.Rectangle.NO_BORDER
table.TotalWidth = 200.0F
table.LockedWidth = True
Dim cell As PdfPCell
cell = New PdfPCell()
cell.AddElement(New iTextSharp.text.Paragraph(ds.Tables(0).Rows(k)("id").ToString(), times))
cell.AddElement(New iTextSharp.text.Paragraph(ds.Tables(0).Rows(k)("name").ToString() + " " + dsLabelTemp.Tables(0).Rows(k)("city").ToString() + "(" + dsLabelTemp.Tables(0).Rows(k)("post").ToString() + ")", times))
cell.AddElement(New iTextSharp.text.Paragraph(ds.Tables(0).Rows(k)("userpersonal").ToString(), times))
cell.Colspan = 3
cell.HorizontalAlignment = 0
cell.Border = iTextSharp.text.Rectangle.NO_BORDER
cell.Padding = 20.0F
table.AddCell(cell)
table.WriteSelectedRows(0, -1, document.Left + spacing, curY, writer.DirectContent)
spacing = spacing + 200
lineHeight = Math.Max(lineHeight, table.TotalHeight)
If 0 = (k + 1) Mod maxPerLine Then
curY = curY - lineHeight
spacing = 0
lineHeight = 0
End If
Next
document.Close()
ShowPdf(filename)
When above code execute in perfect manner and gives the output but it is not showing the if page 1 completed .
In above image you can check that it is not showing full records.
I want to break the page if the page is full or increase the page hight.
How can i transfer data to second page if my 1st page is full ??
I got the solution.
Below is my new code:
Dim table As PdfPTable
table = New PdfPTable(4)
table.DefaultCell.Border = iTextSharp.text.Rectangle.NO_BORDER
table.TotalWidth = 400.0F
table.LockedWidth = True
For k As Integer = 0 To ds.Tables(0).Rows.Count - 1
Dim cell As PdfPCell
cell = New PdfPCell()
cell.AddElement(New iTextSharp.text.Paragraph(ds.Tables(0).Rows(k)("id").ToString(), times))
cell.AddElement(New iTextSharp.text.Paragraph(ds.Tables(0).Rows(k)("name").ToString() + " " + dsLabelTemp.Tables(0).Rows(k)("city").ToString() + "(" + dsLabelTemp.Tables(0).Rows(k)("post").ToString() + ")", times))
cell.AddElement(New iTextSharp.text.Paragraph(ds.Tables(0).Rows(k)("userpersonal").ToString(), times))
cell.Colspan = 1
cell.HorizontalAlignment = 0
cell.Border = iTextSharp.text.Rectangle.NO_BORDER
cell.Padding = 20.0F
table.AddCell(cell)
Next
document.Add(table)
document.Close()
ShowPdf(filename)

Datatable Select all rows

I want to insert into table for specific columns into table using select * from datatable.But it is giving me an array .. is there any way I can get the Insert work.
all I want to do is
Insert into table1 (id,name,status) select * from datatable
query += "Insert into " + tableName.ToLower() + "";
query += "(";
for (int i = 0; i < dt.Columns.Count; i++)
{
if (i != dt.Columns.Count - 1)
query += dt.Columns[i].ColumnName.ToLower() + ",";
else
query += dt.Columns[i].ColumnName.ToLower();
}
query += ")";
DataRow[] result = dt.Select();
query += "select * from " + result
You Can't use two sql Statements at once like that you have to separate them in two different objects or variables (It's sometimes allowed when you end each by a semicolon ; but not in your case )
try to get each cell value in the row
query += "Insert into " + tableName.ToLower() + "";
query += "(";
for (int i = 0; i < dt.Columns.Count; i++)
{
if (i != dt.Columns.Count - 1)
query += dt.Columns[i].ColumnName.ToLower() + ",";
else
query += dt.Columns[i].ColumnName.ToLower();
}
query += ")";
query += "values ( ";
string temQry=query;//you need it more than once
DataRow[] result = dt.Select();
for (int i = 0; i < dt.Rows.Count; i++){
for (int j = 0; j < dt.Columns.Count; j++){
if ((j+1)<dt.Columns.Count){
query += result[i].item(j) +"," ;
}
else {
query += result[i].item(j);}
}
query=temQry; //recover the query for each new row
}

Cannot find column 25 Exception coming

I am creating one report where data exported from my access database to excel here. I'm not using any datagridview , when user click one checkbox appropriate report he can able to download for this I have written code but when I run this code its giving me Cannot find column 25, I don't know why its showing me this?
In access table I have total 25 column :
string sql = null;
string data = null;
int i = 0;
int j = 0;
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
xlApp = new Excel.Application();
xlWorkBook = xlApp.Workbooks.Add(misValue);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
string connectionString = null;
connectionString = ConfigurationManager.ConnectionStrings["AccessConnectionString"].ConnectionString;
cnn.ConnectionString = connectionString;
cnn.Open();
sql = "SELECT * FROM Billing WHERE Bill_No and Bill_Date is null order by FormNo desc";
OleDbDataAdapter dscmd = new OleDbDataAdapter(sql, cnn);
DataSet ds = new DataSet();
dscmd.Fill(ds);
cnn.Close();
for (j = 0; i < ds.Tables[0].Columns.Count; j++)
{
xlWorkSheet.Cells[1, j + 1] = ds.Tables[0].Columns[j].Caption; // Exception coming this line
}
for (i = 0; i < ds.Tables[0].Rows.Count; i++)
{
for (j = 0; j < ds.Tables[0].Columns.Count; j++)
{
data = ds.Tables[0].Rows[i].ItemArray[j].ToString();
xlWorkSheet.Cells[i + 2, j + 1] = data;
}
}
System.Windows.Forms.SaveFileDialog saveDlg = new System.Windows.Forms.SaveFileDialog();
saveDlg.InitialDirectory = #"C:\";
saveDlg.Filter = "Excel files (*.xls)|*.xls";
saveDlg.FilterIndex = 0;
saveDlg.RestoreDirectory = true;
saveDlg.Title = "Export Excel File To";
xlWorkBook.Close(true, misValue, misValue);
MessageBox.Show("File Downloaded successfully...");
xlApp.Quit();
}
i got the answer here i change my for loop
for (i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
{
for (j = 0; j <= ds.Tables[0].Columns.Count - 1; j++)
{
xlWorkSheet.Cells[1, j + 1] = ds.Tables[0].Columns[j].Caption;
data = ds.Tables[0].Rows[i].ItemArray[j].ToString();
xlWorkSheet.Cells[i + 2, j + 1] = data;
}
}

How to re arrange characters in a string?

here is the following code which works just fine:
sCharacterUid = "394F73";
size_t pos;
sPos1 = sCharacterUid.substr(4,1);
sPos2 = sCharacterUid.substr(5,1);
sPos3 = sCharacterUid.substr(2,1);
sPos4 = sCharacterUid.substr(3,1);
sPos5 = sCharacterUid.substr(0,1);
sPos6 = sCharacterUid.substr(1,1);
sCharacterUid = sPos1 + sPos2 + " " + sPos3 + sPos4 + " " + sPos5 + sPos6;
String^ sfCharacterUid = gcnew String(sCharacterUid.c_str());
but I am wondering how I can cut down the amount of code needed to perform this task.
This is in c++/cli.
Thanks.
at first glance, why not
sPos1 = sCharacterUid.substr(4,2);
sPos3 = sCharacterUid.substr(2,2);
sPos5 = sCharacterUid.substr(0,2);
sCharacterUid = sPos1 + " " + sPos3 + " " + sPos5;
Or
string result="";
for (i=4;i>=0;i-=2)
result += sCharacterUid.substr(i,2) + " ";
Or, it may be more efficient to work with raw chars.
char result=[9];
char* dest=result;
char* source = sCharacterUid.c_str();
for (i=4;i>=0;i-=2)
{
*dest++ = source[i];
*dest++ = source[i+1];
*dest++ = ' ';
}
*(--dest)='\0';
String^ sfCharacterUid = gcnew String(result);
std::string & S = sCharacterUid;
S = S.substr (4, 2) + " " + S.substr (2, 2) + " " + S.substr (0, 2);