Adding text to a PDF file from a text file [duplicate] - c#

This question already has answers here:
Convert TXT file to PDF using iText (keep formatting)
(3 answers)
Closed 6 years ago.
This is my code:
using (FileStream msReport = new FileStream(pdfPath, FileMode.Create))
{
//step 1
using (Document pdfDoc = new Document(PageSize.A4, 10f, 10f, 140f, 10f))
{
try
{
// step 2.
StreamReader sr = new StreamReader("TextFile.txt");
string line;
PdfWriter pdfWriter = PdfWriter.GetInstance(pdfDoc, msReport);
pdfWriter.PageEvent = new ITextEvents();
//open the stream
pdfDoc.Open();
for (int i = 0; i < 100; i++)
{
if ((line = sr.ReadLine()) != null)
{
Paragraph para = new Paragraph(line, new iTextSharp.text.Font(iTextSharp.text.Font.FontFamily.HELVETICA, 6));
para.Alignment = Element.ALIGN_LEFT;
pdfDoc.Add(para);
//pdfDoc.NewPage();
}
}
sr.Close();
pdfDoc.Close();
and it's working...It reads the text file that is in my computer and adds it to PDF... The problem is - it doesn't keep the formatting from the text file. It just adds text. And I need to keep it the way it is. Is there any way to keep the formatting of the text? Can I somehow add it to a table and format the table, or something like that?

Try this one
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using iTextSharp;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace TxtToPdf
{
class Program
{
static void Main(string[] args)
{
//Read the Data from Input File
StreamReader rdr = new StreamReader("Path/Test.txt");
//Create a New instance on Document Class
Document doc = new Document();
//Create a New instance of PDFWriter Class for Output File
PdfWriter.GetInstance(doc, new FileStream("Path/Test.pdf", FileMode.Create));
//Open the Document
doc.Open();
//Add the content of Text File to PDF File
doc.Add(new Paragraph(rdr.ReadToEnd()));
//Close the Document
doc.Close();
//Open the Converted PDF File
System.Diagnostics.Process.Start("Path/Test.pdf");
}
}
}

You can do it by reading escape sequence too like when line changes you should Read it as \n and then write it in PDF with your text.

Related

Saving PDF to Local Disk C#

I am trying to save a PDF to the document folder. I have googled and came across a lot of resources but none of them worked for me. I have tried using showfiledialog which did not work. What I want is to save my PDF file to the documents folder. I need this done for a school project and this is the only part that has stumped me. So far this is my code:
private void savePDF_Click(object sender, EventArgs e)
{
FileStream fileStream = new FileStream(nameTxtB.Text + "Repair.pdf", FileMode.Create, FileAccess.Write, FileShare.None);
Document document = new Document();
PdfWriter pdfWriter = PdfWriter.GetInstance(document, fileStream);
pdfWriter.Open();
PdfContentByte cb = pdfWriter.DirectContent;
ColumnText ct = new ColumnText(cb);
document.Open();
...
You should add your content (nameTxtB.Text) to Paragraph not to FileStream
using System.IO;
using iTextSharp.text.pdf;
using iTextSharp.text;
static void Main(string[] args) {
// open the writer
string fileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Repair.pdf");
FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write);
Document doc = new Document();
//Create a New instance of PDFWriter Class for Output File
PdfWriter.GetInstance(doc, fs);
//Open the Document
doc.Open();
//Add the content of Text File to PDF File
doc.Add(new Paragraph("Document Content"));
//Close the Document
doc.Close();
System.Diagnostics.Process.Start(fileName);
}

Not able to get Unicode support for different languages

public PDFFormFillerResult CreateHtmlToPdfMemoryStream(string sHtmlText)
{
//Create a stream that we can write to, in this case a MemoryStream
using (var ms = new MemoryStream())
{
//Create an iTextSharp Document which is an abstraction of a PDF but **NOT** a PDF
var doc = new iTextSharp.text.Document();
//Create a writer that's bound to our PDF abstraction and our stream
var writer = PdfWriter.GetInstance(doc, ms);
//Open the document for writing
doc.Open();
var example_html = sHtmlText;
//Create a new HTMLWorker bound to our document
var htmlWorker = new iTextSharp.text.html.simpleparser.HTMLWorker(doc);
FontFactory.Register(Path.Combine(Environment.CurrentDirectory + "\\Library\\arial.ttf"), "Arial"); // just give a path of arial.ttf
StyleSheet css = new StyleSheet();
css.LoadTagStyle("body", "face", "Garamond");
css.LoadTagStyle("body", "encoding", "Identity-H");
css.LoadTagStyle("body", "size", "12pt");
htmlWorker.SetStyleSheet(css);
// htmlWorker.StartDocument();
//HTMLWorker doesn't read a string directly but instead needs a TextReader (which StringReader subclasses)
using (var sr = new StringReader(example_html)) // using (TextReader sr = new StreamReader(example_html, Encoding.UTF8))
{
//Parse the HTML
htmlWorker.Parse(sr);
}
doc.Close();
return new PDFFormFillerResult(ms, PDFFormFillerResultType.Success, string.Empty);
}
}
I need the output as ByteStream as I am merging multiple documents to create one pdf at the end. This works well for English, but when I try using other languages like Russian, Korean, Combodian, etc only the english text which are in template gets displayed.

IOError on file deletion

The following code is used for watermarking pdf :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace WaterDocument
{
class Program
{
static void Main(string[] args)
{
string FileLocation = "C:\\Users\\Desktop\\Hello.pdf";
// string watermarkedFile = "Watermarked.pdf";
// Creating watermark on a separate layer
// Creating iTextSharp.text.pdf.PdfReader object to read the Existing PDF Document
PdfReader reader1 = new PdfReader(FileLocation);
using (FileStream fs = new FileStream(FileLocation.Replace(".pdf","[temp][file].pdf"), FileMode.Create))
// Creating iTextSharp.text.pdf.PdfStamper object to write Data from iTextSharp.text.pdf.PdfReader object to FileStream object
using (PdfStamper stamper = new PdfStamper(reader1, fs))
{
// Getting total number of pages of the Existing Document
int pageCount = reader1.NumberOfPages;
// Create New Layer for Watermark
PdfLayer layer = new PdfLayer("WatermarkLayer", stamper.Writer);
// Loop through each Page
for (int i = 1; i <= pageCount; i++)
{
// Getting the Page Size
Rectangle rect = reader1.GetPageSize(i);
// Get the ContentByte object
PdfContentByte cb = stamper.GetUnderContent(i);
// Tell the cb that the next commands should be "bound" to this new layer
cb.BeginLayer(layer);
cb.SetFontAndSize(BaseFont.CreateFont(
BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED), 50);
PdfGState gState = new PdfGState();
gState.FillOpacity = 0.25f;
cb.SetGState(gState);
cb.SetColorFill(BaseColor.BLACK);
cb.BeginText();
cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "Confidential", rect.Width / 2, rect.Height / 2, 45f);
cb.EndText();
// Close the layer
cb.EndLayer();
}
stamper.Close();
}
File.Delete(FileLocation); //error on this line
File.Move(FileLocation.Replace(".pdf", "[temp][file].pdf"), FileLocation);
}
}
}
On this line I am getting the error
File.Delete(FileLocation);
It is throwing me the following error
The process cannot access the file 'C:\Users\Desktop\Hello.pdf' because it is being used by another process.
How can I find the problem in my code?
You're not calling Close on the PdfReader object reader1, add this before the File.Delete call:
reader1.Close()
You should also consider adding a curly brace after this line:
using (FileStream fs = new FileStream(FileLocation.Replace(".pdf","[temp][file].pdf"), FileMode.Create))
There's a risk you add a line directly below that line and your code will stop working as the using statement is terminated directly on the row below.

How to display text in a pdf file?

I am using c#.net and need for some data to be displayed in a .pdf file. I am able to do so by using a PdfTable but then it is displayed in a tabular format.
I want a simple format like:
I dont want the exact tabular format.I am using iTextSharp dll.
Is it possible to display data in the above metioned format?
Any suggestions are welcome..
You can use PdfParagraph class to render genreal text in PDF
So when you say that you don't want exact tabular format are you talking about the borders? If so, I'd recommend using a PdfPTable and turning the borders off then. Cells in a PdfPTable are all based on the table's DefaultCell, so to turn the borders off for a table called t you'd do this:
t.DefaultCell.Border = 0;
Below is a full working WinForms app targetting iTextSharp 5.1.1.0 that does exactly that:
//PdfPTable Example
using System;
using System.ComponentModel;
using System.IO;
using System.Windows.Forms;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//PDF file to output
string outputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Output.pdf");
//Create a basic stream to write to
using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None))
{
//Create a new PDF document
using (Document doc = new Document())
{
//Bind a the document to the stream
using (PdfWriter w = PdfWriter.GetInstance(doc, fs))
{
//Open our PDF for writing
doc.Open();
//Insert a new page into our output PDF
doc.NewPage();
//Create a three column table
PdfPTable t = new PdfPTable(3);
//Remove the border from the table
t.DefaultCell.Border = 0;
//For the first row we some extra padding
t.DefaultCell.PaddingBottom = 10;
t.AddCell("ColumnA");
t.AddCell("ColumnB");
t.AddCell("ColumnC");
//Reset the padding for the remaining cells
t.DefaultCell.PaddingBottom = 0;
t.AddCell("Value1");
t.AddCell("Value1");
t.AddCell("Value1");
t.AddCell("Value2");
t.AddCell("Value2");
t.AddCell("Value2");
//Add the table to the document
doc.Add(t);
//Close our output PDF
doc.Close();
}
}
}
this.Close();
}
}
}
If for some reason you don't want to do this with a PdfPTable you can try hacking it together with a Paragraph but unless alignment isn't important you are going to give yourself a headache. The sample below uses paragraphs and formats each "column" within the paragraph to be 20 characters each, padding spaces as necessary. NOTE: This is 20 characters of a variable-width font so things don't actually align. If you want that, either use the PdfPTable above or you are going to have to measure strings which is not fun.
//Paragraph Example
using System;
using System.ComponentModel;
using System.IO;
using System.Windows.Forms;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//PDF file to output
string outputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Output.pdf");
//Create a basic stream to write to
using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None))
{
//Create a new PDF document
using (Document doc = new Document())
{
//Bind a the document to the stream
using (PdfWriter w = PdfWriter.GetInstance(doc, fs))
{
//Open our PDF for writing
doc.Open();
//Insert a new page into our output PDF
doc.NewPage();
//Right-pad each "column" for a total of 20 characters
string FormatString = "{0,-20}{1,-20}{2,-20}";
//Add the first row
doc.Add(new Paragraph(String.Format(FormatString, "ColumnA", "ColumnB", "ColumnC")));
//Add a blank line
doc.Add(new Paragraph(""));
//Add the two data rows
doc.Add(new Paragraph(String.Format(FormatString, "Value1", "Value1", "Value1")));
doc.Add(new Paragraph(String.Format(FormatString, "Value2", "Value2", "Value2")));
//Close our output PDF
doc.Close();
}
}
}
this.Close();
}
}
}
In iTextSharp dll, you just pass your data by creating table/tr/td structure in string like this :
string strData = string.Emrty;
strData = "<table border='0' cellpadding='0' cellspacing='0' width='100%'>";
strData += "<tr>";
strData += "<td>";
strData += "</td>";
strData += "</tr>";
strData += "</table>";
by creating table/tr/td structure of your data, just pass this variable data to pdf, then you will get your resulted output in pdf.

Create PDF in memory instead of physical file

How do one create PDF in memorystream instead of physical file using itextsharp.
The code below is creating actual pdf file.
Instead how can I create a byte[] and store it in the byte[] so that I can return it through a function
using iTextSharp.text;
using iTextSharp.text.pdf;
Document doc = new Document(iTextSharp.text.PageSize.LETTER, 10, 10, 42, 35);
PdfWriter wri = PdfWriter.GetInstance(doc, new FileStream("c:\\Test11.pdf", FileMode.Create));
doc.Open();//Open Document to write
Paragraph paragraph = new Paragraph("This is my first line using Paragraph.");
Phrase pharse = new Phrase("This is my second line using Pharse.");
Chunk chunk = new Chunk(" This is my third line using Chunk.");
doc.Add(paragraph);
doc.Add(pharse);
doc.Add(chunk);
doc.Close(); //Close document
Switch the filestream with a memorystream.
MemoryStream memStream = new MemoryStream();
PdfWriter wri = PdfWriter.GetInstance(doc, memStream);
...
return memStream.ToArray();
using iTextSharp.text;
using iTextSharp.text.pdf;
Document doc = new Document(iTextSharp.text.PageSize.LETTER, 10, 10, 42, 35);
byte[] pdfBytes;
using(var mem = new MemoryStream())
{
using(PdfWriter wri = PdfWriter.GetInstance(doc, mem))
{
doc.Open();//Open Document to write
Paragraph paragraph = new Paragraph("This is my first line using Paragraph.");
Phrase pharse = new Phrase("This is my second line using Pharse.");
Chunk chunk = new Chunk(" This is my third line using Chunk.");
doc.Add(paragraph);
doc.Add(pharse);
doc.Add(chunk);
}
pdfBytes = mem.ToArray();
}
I've never used iTextPDF before but it sounded interesting so I took upon the challenge and did some research on my own. Here's how to stream the PDF document via memory.
protected void Page_Load(object sender, EventArgs e)
{
ShowPdf(CreatePDF2());
}
private byte[] CreatePDF2()
{
Document doc = new Document(PageSize.LETTER, 50, 50, 50, 50);
using (MemoryStream output = new MemoryStream())
{
PdfWriter wri = PdfWriter.GetInstance(doc, output);
doc.Open();
Paragraph header = new Paragraph("My Document") {Alignment = Element.ALIGN_CENTER};
Paragraph paragraph = new Paragraph("Testing the iText pdf.");
Phrase phrase = new Phrase("This is a phrase but testing some formatting also. \nNew line here.");
Chunk chunk = new Chunk("This is a chunk.");
doc.Add(header);
doc.Add(paragraph);
doc.Add(phrase);
doc.Add(chunk);
doc.Close();
return output.ToArray();
}
}
private void ShowPdf(byte[] strS)
{
Response.ClearContent();
Response.ClearHeaders();
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment; filename=" + DateTime.Now);
Response.BinaryWrite(strS);
Response.End();
Response.Flush();
Response.Clear();
}
Where your code has new FileStream, pass in a MemoryStream you've already created. (Don't just create it inline in the call to PdfWriter.GetInstance - you'll want to be able to refer to it later.)
Then call ToArray() on the MemoryStream when you've finished writing to it to get a byte[]:
using (MemoryStream output = new MemoryStream())
{
PdfWriter wri = PdfWriter.GetInstance(doc, output);
// Write to document
// ...
return output.ToArray();
}
I haven't used iTextSharp, but I suspect some of these types implement IDisposable - in which case you should be creating them in using statements too.

Categories