How can I add dynamically a textBox value using ItextSharp? - c#

Hi I'm using a ITextSharp to create a PDF. This is my code:
private void FillForm()
{
_path = HttpContext.Current.Server.MapPath("~/") + "\\PDF";
string formFile = _path + "\\Test.pdf";
string newFile = _path + "\\Test2.pdf";
var reader = new PdfReader(formFile);
using (var stamper = new PdfStamper(reader, new FileStream(newFile, FileMode.Create)))
{
AcroFields fields = stamper.AcroFields;
var conn = new SqlConnection(DataManager.ConnectionString);
conn.Open();
var command = new SqlCommand("SQLCommand"), conn);
var dt = new DataTable();
var adapter = new SqlDataAdapter(command);
adapter.Fill(dt);
int rowIndex = 1;
for (int i=0; i < dt.Rows.Count; i++)
{
var name = (string)dt.Rows[i]["Parameter"];
fields.SetField("txt_" + rowIndex, name);
rowIndex++;
}
stamper.FormFlattening = false;
stamper.Close();
}
}
I have a problem when I'm trying to fill the userName into textboxes. I have a list of names that I get it from the SQL query and I want to display it in different textboxes.
Only the first textBox display its value. For the others I must click on textBox to view the value inside.
Does anyone have any idea how I can fix it?

One line is missing in your code:
fields.GenerateAppearances = true;
You need to add this line right after:
AcroFields fields = stamper.AcroFields;
Why is this happening? Your template is somewhat wrong (maybe it was created using OpenOffice): it says that the software used to fill out the form shouldn't generate the appearances of the fields. As a result the value of the field is added (this is proven by the fact that the text appears when you click it), but the appearance is missing (hence the blank fields).

Related

How to merge mutliple CSV files into one with newline after each dataset

I wrote a method which creates a list of strings. The string's values are accountance data.
When I click on a button, a new .csv-file will be created.
It looks like this:
As you can see, there is no newline carriage return feed at the end of the line.
I would like to combine all of these .csv files to 1, each dataset for 1 row.
I tried that manually with this simple cmd copy command copy *.csv allcsv.csv but they are all appended in the first row instead of added to the next row:
What do I need to add/change in my code to include the newline character at the end of each row?
How could I include the cmd copy command in my method the easiest way possible?
private void BuchungssatzBilden(object obj)
{
//Lieferschein-Buchungswerte in Liste speichern
List<string> bs = new List<string>();
bs.Add(SelItem.Umsatz.ToString());
bs.Add(SelItem.Gegenkonto);
bs.Add(SelItem.Beleg);
bs.Add(SelItem.Buchungsdatum);
bs.Add(SelItem.Konto);
bs.Add(SelItem.Kost1);
bs.Add(SelItem.Kost2);
bs.Add(SelItem.Text);
using (var stream = new MemoryStream())
using (var reader = new StreamReader(stream))
using (var sr = new StreamWriter(#"C:\" + SelItem.Beleg + SelItem.Text + SelItem.Hv + ".csv", true, Encoding.UTF8))
{
using (var csv = new CsvWriter(sr, System.Globalization.CultureInfo.CurrentCulture))
{
//csv.Configuration.Delimiter = ";";
//csv.Configuration.HasHeaderRecord = true;
foreach (var s in bs)
{
csv.WriteField(s);
}
csv.Flush();
stream.Position = 0;
reader.ReadToEnd();
}
}
MessageBox.Show("CSV erfolgreich erstellt!");
}

Fill dynamic Column Data in Rows.Add in Datagrid, Winform

I'm trying to fill a Datagrid with the data fetched from a CSV file.
But I wish to add Columns dynamically, as the number of columns vary in my CSV files.
I don't wish to predefined the Column count in my 'Rows.Add' as below-
dataTable.Rows.Add(totalData[0], totalData[1], totalData[2], totalData[3]);
I have tried two other approaches, but in those don't do the trick.
Below is my code-
using (var selectFileDialog = new OpenFileDialog())
{
if (selectFileDialog.ShowDialog() == DialogResult.OK)
{
string filePath = selectFileDialog.FileName.ToString();
StreamReader streamReader = new StreamReader(filePath);
string[] totalData = new string[File.ReadAllLines(filePath).Length];
DataTable dataTable = new DataTable();
//Fill DataGrid Column Names
totalData = streamReader.ReadLine().Split(';');
for(int i=0; i< totalData.Length; i++)
{ dataTable.Columns.Add(totalData[i]); }
//Fill DataGrid DATA
while (!streamReader.EndOfStream)
{
totalData = streamReader.ReadLine().Split(';');
//METHOD 1: Need a Replacement for this. Dont want a predefined it.
dataTable.Rows.Add(totalData[0], totalData[1], totalData[2], totalData[3]);
//METHOD 2: Doesn't Work. Fills the entire data in the very first column
for (int i = 0; i < totalData.Length; i++)
{ dataTable.Rows.Add(totalData[i]); }
//METHOD 3: Doesn't Work. Throws a Null Pointer Exception.
dgDataFromCSV.Rows[0].Cells[0].Value = "test";
}
dgDataFromCSV.DataSource = dataTable;
}
}
Open for any idea, or nay other method/approach to achieve it.
You could use dataTable.NewRow() to create a new empty DataRow, then use a loop to assign the values to the DataRow and finally attach the DataRow to the table with dataTable.Rows.Add(newDataRow).

Generate PDF in using windows form

I want to generate a PDF using windows form in the desktop application. I have readymade pdf design and I just want to feed data from database in that blank section of pdf for each user. (One type of receipt). Please guide me. I have searched but most of the time there is the solution in asp.net for the web application. I want to do in the desktop app. Here is my code I am able to fatch data from database and print in pdf. But main problem is trhat I have already designed pdf and I want to place data exactly at same field (ie name, Amount, date etc.)
using System;
using System.Windows.Forms;
using System.Diagnostics;
using PdfSharp;
using PdfSharp.Drawing;
using PdfSharp.Pdf;
using System.Data.SqlClient;
using System.Data;
using System.Configuration;
namespace printPDF
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click_1(object sender, EventArgs e)
{
try
{
string connetionString = null;
SqlConnection connection ;
SqlCommand command ;
SqlDataAdapter adapter = new SqlDataAdapter();
DataSet ds = new DataSet();
int i = 0;
string sql = null;
int yPoint = 0;
string pubname = null;
string city = null;
string state = null;
connetionString = "Data Source=EEVO-SALMAN\\MY_PC;Initial Catalog=;User ID=s***;Password=******";
// var connectionString = ConfigurationManager.ConnectionStrings["CharityManagement"].ConnectionString;
sql = "select NAME,NAME,uid from tblumaster";
connection = new SqlConnection(connetionString);
connection.Open();
command = new SqlCommand(sql, connection);
adapter.SelectCommand = command;
adapter.Fill(ds);
connection.Close();
PdfDocument pdf = new PdfDocument();
pdf.Info.Title = "Database to PDF";
PdfPage pdfPage = pdf.AddPage();
XGraphics graph = XGraphics.FromPdfPage(pdfPage);
XFont font = new XFont("Verdana", 20, XFontStyle.Regular );
yPoint = yPoint + 100;
for (i = 0; i <=ds.Tables[0].Rows.Count-1; i++)
{
pubname = ds.Tables[0].Rows[i].ItemArray[0].ToString ();
city = ds.Tables[0].Rows[i].ItemArray[1].ToString();
state = ds.Tables[0].Rows[i].ItemArray[2].ToString();
graph.DrawString(pubname, font, XBrushes.Black, new XRect(10, yPoint, pdfPage.Width.Point, pdfPage.Height.Point), XStringFormats.TopLeft);
graph.DrawString(city, font, XBrushes.Black, new XRect(200, yPoint, pdfPage.Width.Point, pdfPage.Height.Point), XStringFormats.TopLeft);
graph.DrawString(state, font, XBrushes.Black, new XRect(400, yPoint, pdfPage.Width.Point, pdfPage.Height.Point), XStringFormats.TopLeft);
yPoint = yPoint + 40;
}
string pdfFilename = "dbtopdf.pdf";
pdf.Save(pdfFilename);
Process.Start(pdfFilename);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
}
Instead of modifying the document, please create a new document and copy the pages from the old document to new document
sample code can be found here,
http://forum.pdfsharp.net/viewtopic.php?p=2637#p2637
Because modifying pdf is not recommended using 'PdfSharp' library. if you still want to edit you can use 'ISharp' library which needs a license.
Here is some VB.Net code I use to fill PDF forms. You need a PDF fillable form with form control names matching the SQL record field names.
It calls a routine Gen.GetDataTable() that just builds a typical DataTable. You could re-code to accept a pre-built Datatable as a parameter. Only the top row is processed. The code can be modified to work with a DataRow (.Table.Columns for column reference) or a DataReader.
Public Function FillPDFFormSQL(pdfMasterPath As String, pdfFinalPath As String, SQL As String, Optional FlattenForm As Boolean = True, Optional PrintPDF As Boolean = False, Optional PrinterName As String = "", Optional AllowMissingFields As Boolean = False) As Boolean
' case matters SQL <-> PDF Form Field Names
Dim pdfFormFields As AcroFields
Dim pdfReader As PdfReader
Dim pdfStamper As PdfStamper
Dim s As String = ""
Try
If pdfFinalPath = "" Then pdfFinalPath = pdfMasterPath.Replace(".pdf", "_Out.pdf")
Dim newFile As String = pdfFinalPath
pdfReader = New PdfReader(pdfMasterPath)
pdfStamper = New PdfStamper(pdfReader, New FileStream(newFile, FileMode.Create))
pdfReader.Close()
pdfFormFields = pdfStamper.AcroFields
Dim dt As DataTable = Gen.GetDataTable(SQL)
For i As Integer = 0 To dt.Columns.Count - 1
s = dt.Columns(i).ColumnName
If AllowMissingFields Then
If pdfFormFields.Fields.ContainsKey(s) Then
pdfFormFields.SetField(s, dt.Rows(0)(i).ToString.Trim)
Else
Debug.WriteLine($"Missing PDF Field: {s}")
End If
Else
pdfFormFields.SetField(s, dt.Rows(0)(i).ToString.Trim)
End If
Next
' flatten the form to remove editing options
' set it to false to leave the form open for subsequent manual edits
If My.Computer.Keyboard.CtrlKeyDown Then
pdfStamper.FormFlattening = False
Else
pdfStamper.FormFlattening = FlattenForm
End If
pdfStamper.Close()
If Not newFile.Contains("""") Then newFile = """" & newFile & """"
If Not PrintPDF Then
Process.Start(newFile)
Else
Dim sPDFProgramPath As String = INI.GetValue("OISForms", "PDFProgramPath", "C:\Program Files (x86)\Foxit Software\Foxit PhantomPDF\FoxitPhantomPDF.exe")
If Not IO.File.Exists(sPDFProgramPath) Then MsgBox("PDF EXE not found:" & vbNewLine & sPDFProgramPath) : Exit Function
If PrinterName.Length > 0 Then
Process.Start(sPDFProgramPath, "/t " & newFile & " " & PrinterName)
Else
Process.Start(sPDFProgramPath, "/p " & newFile)
End If
End If
Return True
Catch ex As Exception
MsgBox(ex.Message)
Return False
Finally
pdfStamper = Nothing
pdfReader = Nothing
End Try
End Function

Conditional Formatting using EPPlus

I am trying to achieve the following: I have a C# application which does some data processing and then outputs to a .xlsx using EPPlus. I want to add some conditional formatting to the excel and tried the following method, first I made a template blank excel with all conditional formatting rules set up and then tried dumping the data in it. The snippet below is my approach. p is an Excel package. Currently this does not work, the data is written correctly however the formatting rules that I set up are lost. I'm guessing because it basically clears everything before writing. Any help will be appreciated!
Byte[] bin = p.GetAsByteArray();
File.Copy("C:\\template.xlsx", "C:\\result.xlsx");
using (FileStream fs = File.OpenWrite("C:\\result.xlsx")) {
fs.Write(bin, 0, bin.Length);
}
Note :: I tried the following as well to avoid the whole external template situation.. check snippet below. The problem with this is that, after the .xlsx is generated and I open it, it says the file has unreadable or not displayable content and that it needs to repair it and after I do that, everything is fine and the conditional formatting has also worked. I have no clue why its doing that or how I can get rid of the error upon file opening.
string _statement = "$E1=\"3\"";
var _cond = ws.ConditionalFormatting.AddExpression(_formatRangeAddress);
_cond.Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
_cond.Style.Fill.BackgroundColor.Color = Color.LightCyan;
_cond.Formula = _statement;
Any help will be appreciated!!
The method of using fs.Write will simply overwrite the copied file with the epplus generated file since you are doing it at the byte/stream level. So that will not get you what you want. (#MatthewD was showing you this in his post).
As for applying the format itself, what you have should work but if you are getting that kind of error I suspect you are mixing epplus and non-epplus manipulation of the excel file. This is how you should be doing it roughly:
[TestMethod]
public void Conditional_Format_Test()
{
//http://stackoverflow.com/questions/31296039/conditional-formatting-using-epplus
var existingFile = new FileInfo(#"c:\temp\temp.xlsx");
if (existingFile.Exists)
existingFile.Delete();
//Throw in some data
var datatable = new DataTable("tblData");
datatable.Columns.Add(new DataColumn("Col1", typeof(int)));
datatable.Columns.Add(new DataColumn("Col2", typeof(int)));
datatable.Columns.Add(new DataColumn("Col3", typeof(int)));
for (var i = 0; i < 20; i++)
{
var row = datatable.NewRow();
row["Col1"] = i;
row["Col2"] = i * 10;
row["Col3"] = i * 100;
datatable.Rows.Add(row);
}
using (var pack = new ExcelPackage(existingFile))
{
var ws = pack.Workbook.Worksheets.Add("Content");
ws.Cells["E1"].LoadFromDataTable(datatable, true);
//Override E1
ws.Cells["E1"].Value = "3";
string _statement = "$E1=\"3\"";
var _cond = ws.ConditionalFormatting.AddExpression(new ExcelAddress(ws.Dimension.Address));
_cond.Style.Fill.PatternType = ExcelFillStyle.Solid;
_cond.Style.Fill.BackgroundColor.Color = Color.LightCyan;
_cond.Formula = _statement;
pack.SaveAs(existingFile);
}
}
To expand on #Ernie code sample, here's a working example that colors a range according to cell's value. Each cell of the range can have any of three colors depending on the cell's value (<.01, <.05, <.1).
ExcelRange rng = ws.Cells[statsTableRowStart, 10, statsTableRowStart + gud.levels.level.Count() - 1, 10];
OfficeOpenXml.ConditionalFormatting.Contracts.IExcelConditionalFormattingExpression _condp01 = ws.ConditionalFormatting.AddExpression(rng);
_condp01.Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
_condp01.Style.Fill.BackgroundColor.Color = System.Drawing.Color.OrangeRed;
_condp01.Formula = new ExcelFormulaAddress(rng.Address) + "<.01";
OfficeOpenXml.ConditionalFormatting.Contracts.IExcelConditionalFormattingExpression _condp05 = ws.ConditionalFormatting.AddExpression(rng);
_condp05.Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
_condp05.Style.Fill.BackgroundColor.Color = System.Drawing.Color.OliveDrab;
_condp05.Formula = new ExcelFormulaAddress(rng.Address) + "<.05";
OfficeOpenXml.ConditionalFormatting.Contracts.IExcelConditionalFormattingExpression _condp1 = ws.ConditionalFormatting.AddExpression(rng);
_condp1.Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
_condp1.Style.Fill.BackgroundColor.Color = System.Drawing.Color.LightCyan;
_condp1.Formula = new ExcelFormulaAddress(rng.Address) + "<.1";

How to create pdfformfields using iTextSharp?

I am using iTextSharp and CSharp for creating the pdf. I need to add formfields like checkbox, radiobutton and dropdown which can not be edited.
I used this..
FileStream pdffile = new FileStream(path + "/Pdf/tes.pdf",FileMode.Create);
PdfWriter writer = PdfWriter.GetInstance(doc, pdffile);
doc.Open();
Rectangle rect = new Rectangle(100, 100, 100, 100);
RadioCheckField checkbox = new RadioCheckField(writer, rect, "bhjabsdf", "on");
checkbox.CheckType = RadioCheckField.TYPE_CHECK;
PdfFormField field = checkbox.CheckField;
writer.AddAnnotation(field);
doc.Close();
But it's not working. I also read about PdfStamper. But I am creating a new pdf, not changing the existing one.So I don't know whether I can use PdfStamper?
Thanks..
Edit:
private void CreateRadioButton(PdfWriter writer, PdfContentByte cb,Font font)
{
Rectangle rect;
PdfFormField field;
PdfFormField radiogroup = PdfFormField.CreateRadioButton(writer, true);
radiogroup.FieldName = "language";
RadioCheckField radio;
int x = 20;
for (int i = 0; i < Petrol.Length; i++)
{
rect = new Rectangle(440 + i * x, 692, 450 + i * x, 682);
radio = new RadioCheckField(writer, rect, null, LANGUAGES[i]);
radio.BorderColor = GrayColor.GRAYBLACK;
radio.BackgroundColor = BaseColor.WHITE;
radio.CheckType = RadioCheckField.TYPE_CIRCLE;
if (Petrol[i] == "F")
radio.Checked = true;
field = radio.RadioField;
//Here i am setting readonly..
field.SetFieldFlags(PdfFormField.FF_READ_ONLY);
radiogroup.AddKid(field);
ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT,
new Phrase(Petrol[i], font), 451 + i * x, 684, 0);
if (i >= 1) x = 25;
}
writer.AddAnnotation(radiogroup);
}
You're creating a field 'the hard way'. There's a class named RadioCheckField that makes it much easier for you to create a field.
Please take a look at the book examples from Chapter 8. You can find C# versions of the examples here, for instance an example named Buttons.
checkbox = new RadioCheckField(writer, rect, LANGUAGES[i], "on");
checkbox.CheckType = RadioCheckField.TYPE_CHECK;
PdfFormField field = checkbox.CheckField;
You can create your custom form template using LiveCycle and then data bind the form fields using iTextSharp like this
string randomFileName = Helpers.GetRandomFileName();
string formTemplate = Server.MapPath("~/FormTemplate.pdf");
string formOutput = Server.MapPath(string.Format("~/downloads/Forms/Form-{0}.pdf", randomFileName));
PdfReader reader = new PdfReader(formTemplate);
PdfStamper stamper = new PdfStamper(reader, new System.IO.FileStream(formOutput, System.IO.FileMode.Create));
AcroFields fields = stamper.AcroFields;
// set form fields
fields.SetField("Date", DateTime.Now.ToShortDateString());
fields.SetField("FirstName", user.FirstName);
fields.SetField("LastName", user.LastName);
fields.SetField("Address1", user.Address1);
fields.SetField("Address2", user.Address2);
fields.SetField("City", user.City);
fields.SetField("State", user.State);
fields.SetField("Zip", user.Zip);
fields.SetField("Email", user.Email);
fields.SetField("Phone", user.Phone);
// set document info
System.Collections.Hashtable info = new System.Collections.Hashtable();
info["Title"] = "User Information Form";
info["Author"] = "My Client";
info["Creator"] = "My Company";
stamper.MoreInfo = info;
// flatten form fields and close document
stamper.FormFlattening = true;
stamper.Close();
You do not need to use a PdfStamper to create AcroForm form fields in a PDF, PdfWriter also allows you to.
Unfortunately you neither said in which way your code didn't work nor what exact requirements you have; still some sample code might bring you on track:
Have a look at chapter 8 of iText in Action, 2nd edition; especially the sample Buttons will give you numerous hints on how to create radio buttons and check boxes. The sample ChoiceFields will show you how to create list and combo boxes.

Categories