I have a situation where I replicate a pdf from an existing pdf blank 'certificate', The replica pdf contains some personal info that was added to the 'blue print' copy.
After mailing this to the user I want to delete it again so as not to save a copy on the server.
No matter what I do, however, I get the error message
The process cannot access the file 'certificate#672712.pdf' because it is being used by another process.
It is pretty clear what the message means, what I want to know is how I should alter the code for the certificate creation part so that is 'released' after words.
This is the code that I use.
try
{
string suffix = (DateTime.Now.Day % 10 == 1 && DateTime.Now.Day != 11) ? "st of"
: (DateTime.Now.Day % 10 == 2 && DateTime.Now.Day != 12) ? "nd of"
: (DateTime.Now.Day % 10 == 3 && DateTime.Now.Day != 13) ? "rd of"
: "th of";
string dateToday = string.Format("{0:dd}{1} {0:MMMM yyyy}", DateTime.Now, (suffix));
Random generator = new Random();
string referenceNumber = "#" + generator.Next(0, 1000000).ToString("D6");
string bluePrint = HttpContext.Current.Server.MapPath("~/Certificates/blue_print.pdf");
if (certificateNumber != "")
{
referenceNumber = certificateNumber;
}
string certificate = HttpContext.Current.Server.MapPath("~/Certificates/certificate_" + referenceNumber + ".pdf");
PdfReader reader = new PdfReader(bluePrint);
using (PdfStamper stamper = new PdfStamper(reader, new FileStream(certificate, FileMode.Create)))
{
reader.SelectPages("1");
var pageSize = reader.GetPageSize(1);
PdfContentByte pbover = stamper.GetOverContent(1);
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
pbover.SetColorFill(BaseColor.DARK_GRAY);
Font font = new Font(bf);
font.Size = 32;
ColumnText.ShowTextAligned(pbover, Element.ALIGN_LEFT, new Phrase(UserName, font), 90, 305, 0);
}
reader.Close();
return referenceNumber;
}
catch (Exception exe)
{
return exe.Message.ToString();
}
in my controller method I call the methods in this sequence.
//certificate
var reference = UtilityService.GenerateCertificate(String.Format("{0} {1}", firstName, lastName), "");
//Mail the certificate
string message = await MailService.MailTheCertificate(user.Email, "Well done", "Well done on completing the course", reference);
//THE ERROR HAPPENS AS I AM TRYING TO DELETE THE CERTIFICATE
FileInfo file = new FileInfo(HttpContext.Current.Server.MapPath("~/Certificates/certificate_" + reference + ".pdf"));
file.Delete();
return Ok("success");
Related
I would really like to use the newer approach of using PDFStamper instead of using the older approach of (PdfWriter.GetInstance... writer.DirectContent) but the PDF file created using the older method is 1/2 the size then using the newer approach. Is there something I am missing between the two approaches?
//Old way using PdfWriter.GetInstance... writer.DirectContent
public static void AddHeaderTextLayer()
{
string HdrLeft = string.Empty;
string HdrRight = string.Empty;
string PageHdrName = "XHdr";
string NoOfPagesPadded = string.Empty;
string PageNoPadded = string.Empty;
int xLeft = 30;
int xRight = 100;
int xTop = 15;
string filename = "4_20140909.pdf";
PdfReader reader = new PdfReader(#"C:\!stuff\Junk\ChemWatchPDF\" + filename); // input file
using (var fileStream = new FileStream(#"C:\!stuff\Junk\ChemWatchPDF\" + filename.Replace(".pdf", "") + "_withHdrLTp.pdf", FileMode.Create, FileAccess.Write))
{
var document = new Document(reader.GetPageSizeWithRotation(1));
var writer = PdfWriter.GetInstance(document, fileStream);
document.Open();
for (var i = 1; i <= reader.NumberOfPages; i++)
{
Rectangle pageRect = reader.GetPageSize(i);
document.NewPage();
var baseFont = BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
var importedPage = writer.GetImportedPage(reader, i);
var contentByte = writer.DirectContent;
contentByte.AddTemplate(importedPage, 0, 0);
string SDSNo = "12345678";
HdrLeft = $"Company MSDS# {SDSNo}";
NoOfPagesPadded = (reader.NumberOfPages.ToString());
PageNoPadded = i.ToString();
HdrRight = $" Page {PageNoPadded} of {NoOfPagesPadded}";
contentByte.BeginLayer(new PdfLayer(PageHdrName + i.ToString(), writer));
contentByte.BeginText();
contentByte.SetFontAndSize(baseFont, 10);
contentByte.SetColorFill(LabColor.RED);
contentByte.ShowTextAligned(PdfContentByte.ALIGN_LEFT, HdrLeft, pageRect.Left + xLeft, pageRect.Top - xTop, 0);
contentByte.EndText();
contentByte.BeginText();
contentByte.SetFontAndSize(baseFont, 10);
contentByte.SetColorFill(LabColor.RED);
contentByte.ShowTextAligned(PdfContentByte.ALIGN_LEFT, HdrRight, pageRect.Right - xRight, pageRect.Top - xTop, 0);
contentByte.EndText();
contentByte.EndLayer();
}
document.Close();
writer.Close();
}
}
// New way using PDFStamper
public void Add()
{
BaseFont baseFont = BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, Encoding.ASCII.EncodingName, false);
string outPutFile = string.Empty;
var SingleLine = string.Empty;
string HdrLeft = string.Empty;
string HdrRight = string.Empty;
string PageHdrName = "xHdr";
string NoOfPagesPadded = string.Empty;
string PageNoPadded = string.Empty;
int xLeft = 30;
int xRight = 100;
int xTop = 15;
string filename = "4_20140909.pdf";
outPutFile = #"C:\!stuff\Junk\ChemWatchPDF\" + filename.Replace(".pdf", "") + "_withHdrLTStamp.pdf";
using (var newPDF = new FileStream(outPutFile, FileMode.Create, FileAccess.ReadWrite))
{
PdfReader reader = new PdfReader(#"C:\!stuff\Junk\ChemWatchPDF\" + filename); // input file
PdfStamper pdfStamper = new PdfStamper(reader, newPDF);
PdfLayer wmLayer = new PdfLayer(PageHdrName, pdfStamper.Writer);
for (int page = 1; page <= reader.NumberOfPages; page++)
{
PdfContentByte pdfContent = pdfStamper.GetOverContent(page);
Rectangle pageRect = reader.GetPageSize(page);
string SDSNo = "12345678";
HdrLeft = $"Company MSDS# {SDSNo}";
NoOfPagesPadded = (reader.NumberOfPages.ToString());
PageNoPadded = page.ToString();
HdrRight = $"Page {PageNoPadded} of {NoOfPagesPadded}";
pdfContent.BeginLayer(wmLayer);
pdfContent.BeginText();
pdfContent.SetFontAndSize(baseFont, 10);
pdfContent.SetColorFill(LabColor.RED);
pdfContent.ShowTextAligned(PdfContentByte.ALIGN_LEFT, HdrLeft, pageRect.Left + xLeft, pageRect.Top - xTop, 0);
pdfContent.EndText();
pdfContent.BeginText();
pdfContent.SetFontAndSize(baseFont, 10);
pdfContent.SetColorFill(LabColor.RED);
pdfContent.ShowTextAligned(PdfContentByte.ALIGN_LEFT, HdrRight, pageRect.Right - xRight, pageRect.Top - xTop, 0);
pdfContent.EndText();
pdfContent.EndLayer();
}
pdfStamper.Close();
}
}
}
}
Your stamped copy (the output of the "newer approach") contains a structure tree which I assume to come from the original document. It is lost in the output of the "old approach".
The structure tree describes the logical structure of the document. It increases the accessibility of the document and its presence becomes a legal requirement in more and more countries and contexts. Thus, throwing away the structure tree in general is a bad idea.
The structure tree itself consists of very many small indirect objects, in case of your PDF there are more than 1000 indirect objects approximately 90KB in size altogether. Furthermore, each indirect object requires a 20 byte cross reference entry which sums up to nearly 20KB in your case. This explains nearly all of the 111KB difference in size between the two outputs.
If you make use of object streams and cross reference streams, the structure tree can usually be fairly well compressed. Thus, I would propose you activate full compression in iText which makes it use object streams and cross reference streams:
PdfStamper pdfStamper = new PdfStamper(reader, newPDF);
pdfStamper.SetFullCompression();
pdfStamper.Writer.CompressionLevel = 9;
By simply processing your large PDF by a PdfReader/PdfStamper couple with these settings without any other manipulations, I reduced the size of your file from 234KB down to 133KB.
By the way, you call the approach with the PdfWriter and page imports the "old way" and the approach with the PdfStamper the "new way". Actually the PdfStamper class exists in iText at least since 2003! So it's not really old vs. new...
I have a code to delete file in my folder, but in my line code, I want to delete two file together with different folder. But I always get an error "the process cannot access.... another process". May be you can correct my code and give me a solution. Thanks
1) I have a code to generate watermark when save file(.pdf):
public bool InsertWaterMark(string path)
{
bool valid = true;
string FileDestination = AppDomain.CurrentDomain.BaseDirectory + "Content/" + path;
string FileOriginal = AppDomain.CurrentDomain.BaseDirectory + "Content/" + path.Replace("FileTemporary", "FileOriginal");
System.IO.File.Copy(FileDestination, FileOriginal);
string watermarkText = "Controlled Copy";
#region process
PdfReader reader1 = new PdfReader(FileOriginal);//startFile
using (FileStream fs = new FileStream(FileDestination, FileMode.Create, FileAccess.Write, FileShare.None))//watermarkedFile
{
using (PdfStamper stamper = new PdfStamper(reader1, fs))
{
int pageCount1 = reader1.NumberOfPages;
PdfLayer layer = new PdfLayer("WatermarkLayer", stamper.Writer);
for (int i = 1; i <= pageCount1; i++)
{
iTextSharp.text.Rectangle rect = reader1.GetPageSize(i);
PdfContentByte cb = stamper.GetUnderContent(i);
cb.BeginLayer(layer);
cb.SetFontAndSize(BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED), 80);
PdfGState gState = new PdfGState();
gState.FillOpacity = 0.15f;
cb.SetGState(gState);
cb.SetColorFill(BaseColor.GRAY);
cb.BeginText();
cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, watermarkText, rect.Width / 2, rect.Height / 2, 45f);
cb.EndText();
PdfContentByte canvas = stamper.GetUnderContent(i);
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA_OBLIQUE, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
canvas.SetColorFill(BaseColor.RED);
PdfGState gStateFooter = new PdfGState();
gStateFooter.FillOpacity = 1f;
canvas.SetGState(gStateFooter);
canvas.BeginText();
canvas.SetFontAndSize(bf, 12);
canvas.ShowTextAligned(PdfContentByte.ALIGN_CENTER, '"' + "When printed, this documents are considered uncontrolled" + '"', 300.7f, 10.7f, 0);
canvas.EndText();
cb.EndLayer();
}
}
}
#endregion
return valid;
}
2) And this code i call when delete detail data from one page together.
public ActionResult Delete(string parm)
{
TableEDIS data = db.TableEDISs.FirstOrDefault(e => e.detail_guid_edis == new Guid(parm));
string fisikFile = data.upload_document;
string fisikFileFormulir = data.upload_document_formulir;
if (!string.IsNullOrEmpty(fisikFile))
{
var relativePath = "~/Content/" + fisikFile;
var absolutePath = HttpContext.Server.MapPath(relativePath);
var absolutePathOriginal = HttpContext.Server.MapPath(relativePath.Replace("Temporary", "Original"));
if (Directory.Exists(Path.GetDirectoryName(absolutePath)))
{
System.IO.File.Delete(absolutePath);
}
if (Directory.Exists(Path.GetDirectoryName(absolutePathOriginal)))
{
System.IO.File.Delete(absolutePathOriginal);
}
}
}
I hope you understand what I mean.
Thanks in advance.
My spidey senses tells me you need to call
reader1.Close();
I have a big problem and i hope you can help me out.
I have a PDF file which I split in more files.
Problem: There is a table content (goto page X), but in the new pdf files it doesnt work anymore.
I cant find a solution to copy this table content to the new pdf files.
For your understanding:
I have three pdf files which are equal.
PDF:
Page 1:
Text
Page 2:
Contenttable:
Content x Page 3 (Goto Page 3)
Content x Page 4 ""
content x Page 5 ""
...
...
I put all these pdf files together in one big pdf. (Content table still working)
And now, i will split these back in to single once (Content table not working)
My idea was to export the content table out of the original pdf(Where table content is still working) and to import it in the new once.
But i dont know how.
Second idea: search for keywords in the PDF and change the keyword to an goto local page action.
But i find no solution how i can do this.
However in the end i want to repair the table content in each single pdf file.
any ideas?
code so far:
PdfReader reader = null;
Document sourceDocument = null;
Document remote = null;
PdfCopy pdfCopyProvider = null;
PdfImportedPage importedPage = null;
PdfStamper stamp = null;
Chunk chunk = null;
reader = new PdfReader(path);
Seitenanzahl = reader.NumberOfPages;
sourceDocument = Document(reader.GetPageSizeWithRotation(startpage));
tmp = PdfTextExtractor.GetTextFromPage(reader, startpage);
string[] strsplit = tmp.Split(' ');
vorname = strsplit[4];
nachname = strsplit[5];
ort = strsplit[6];
perso = strsplit[7];
vorname = vorname.Replace("\n", "");
vorname = vorname.Replace(" ", "");
nachname = nachname.Replace("\n", "");
nachname = nachname.Replace(" ", "");
ort = ort.Replace("\n", "");
ort = ort.Replace(" ", "");
perso = perso.Replace("\n", "");
perso = perso.Replace(" ", "");
if (Directory.Exists("test/" + ort))
{
}
else
{
DirectoryInfo di = Directory.CreateDirectory("test/" + ort);
}
outputpdfpath = "test/" + ort + "/" + "p_" + ort + "_" + perso + "_" + vorname.ToLower() + "_" + nachname.ToLower() + "_hj1_booklet_2017" + ".pdf";
pdfCopyProvider = new PdfCopy(sourceDocument,
new FileStream(outputpdfpath, FileMode.Create, FileAccess.ReadWrite));
sourceDocument.Open();
for (int i = startpage; i <= endpage; i++)
{
importedPage = pdfCopyProvider.GetImportedPage(reader, i);
pdfCopyProvider.AddPage(importedPage);
}
sourceDocument.Close();
reader.Close();
}
I have created a program which cleans access and error logs and then outputs them in a new file in the same directory. The input is in format .txt and the output is in format .csv - however it is giving me two output files, one in .csv format and one in .txt format(.txt file is empty) instead of just the .csv file? I can't understand why this is happening.
Below is the two ouput files as shown in the directory:
Below is the code which generates the new file with the unique name:
static FileStream CreateFileWithUniqueName(string folder, string fileName, int maxAttempts = 1024)
{
var fileBase = Path.GetFileNameWithoutExtension(fileName);
var ext = Path.GetExtension(fileName);
// build hash set of filenames for performance
var files = new HashSet<string> (Directory.GetFiles(folder));
for (var index = 0; index < maxAttempts; index++)
{
// first try with the original filename, else try incrementally adding an index
var name = (index == 0)
? fileName
: String.Format("{0} ({1}){2}", fileBase, index, ext);
// check if exists
var fullPath = Path.Combine(folder, name);
if(files.Contains(fullPath))
continue;
// try to create the file
try
{
return new FileStream(fullPath, FileMode.CreateNew, FileAccess.Write);
}
catch (DirectoryNotFoundException) { throw; }
catch (DriveNotFoundException) { throw; }
catch (IOException)
{
}
}
throw new Exception("Could not create unique filename in " + maxAttempts + " attempts");
}
And finally the code below is the code which reads in the existing file and cleans it:
public static void readFile(string fileName)
{
using (var stream = CreateFileWithUniqueName(#"C:\Users\michael\Desktop\WindowsFormsApplication1\WindowsFormsApplication1\bin\Debug\", fileName))
{
Console.WriteLine("Created \"" + stream.Name + "\"");
newFileName = stream.Name;
Globals.CleanedErrorFileName = newFileName;
}
string CSVfileName = Path.ChangeExtension(newFileName, ".csv");
StreamReader reader = new StreamReader(fileName);
StreamWriter writer = new StreamWriter(CSVfileName);
string line;
string personalIdentifier = new string(fileName.Take(4).ToArray());
string gender = fileName.Substring(fileName.Length - 5, 1);
string classification = fileName.Substring(fileName.Length - 8, 2);
string text = string.Empty;
while ((line = reader.ReadLine()) != null)
{
string[] cleanArray;
cleanArray = new string[5];
var result = line.Split('[')
.Select((element, index) => index % 2 == 0
? element.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
: new string[] { element })
.SelectMany(element => element).ToList();
cleanArray[0] = personalIdentifier;
cleanArray[1] = gender;
cleanArray[2] = classification;
cleanArray[3] = result[0];
cleanArray[4] = result[2];
cleanArray[4] = cleanArray[4].Substring(7);
cleanArray[4] = cleanArray[4].Replace("]", " ");
cleanArray[4] = cleanArray[4].Insert(15, ",");
cleanArray[3] = cleanArray[3].Remove(cleanArray[3].Length - 2);
cleanArray[4] = cleanArray[4].Substring(0, cleanArray[4].IndexOf(":") + 1);
//re-formatting the date so that it can be accepted by machine learning
var dateString = cleanArray[3];
var date = DateTime.ParseExact(dateString, "ddd MMM dd HH:mm:ss yyyy", CultureInfo.InvariantCulture);
var newDateString = date.ToString("yyyy-MM-dd HH:mm:ss");
//inserting the new date and time into the array
cleanArray[3] = newDateString;
//push each clean array onto the file that has been automatically created at the top
writer.WriteLine(string.Join(", ", cleanArray.Select(v => v.ToString())));
writer.WriteLine();
}
I'm hoping the issue is something small but i can't seem to find it!
Thanks in advance!!
This line is the culprit:
return new FileStream(fullPath, FileMode.CreateNew, FileAccess.Write);
At this point, the file name in fullPath still has .txt extension, this creates the empty .txt file. Then you change extension to .csv and do this:
StreamWriter writer = new StreamWriter(CSVfileName);
which creates the new .csv file
Also, both streams are never closed in your code.
The file creates and emails just fine. But when I attempt to delete or modify it for an indeterminate amount of time thereafter I get the dreaded "Cannot access file because it is in use by another program" message. I've seen it before with documents created in itextsharp, but it was because a PdfStamper was left open. Not sure what it locking it now. Tried using WhoLockMe to see what's going on but it doesn't work on Windows 7 X 64. Tried using LockHunter but it just says that the file isn't locked by any processes. The location of the file is limited to admins and I have confirmed no other admins are in the file when this occurs.
public string SubmitWeekly(string store, string techId, string date, WeeklyHeader header, string latLon, string device, List<CPEquipment> equipment)
{
PdfReader templateReader = null;
PdfReader overFlowReader = null;
PdfStamper templateStamper = null;
PdfStamper overFlowStamper = null;
try
{
string result = "Success";
string year = date.Right(4);
string footerText = string.Format("Submitted {0} near {1} on device {2}", date, latLon, device);
string template = #"C:\Templates\WeeklyInspectionFormCombined.pdf";
string overflowTemplate = #"C:\Templates\WeeklyInspectionOverflowForm.pdf";
string newFile = string.Format(#"C:\Documents\{0}\{1}\Weekly Inspection {2} {3}.pdf", year, techId, store, date);
string overFlowFile = string.Format(#"C:\Documents\{0}\{1}\Weekly Inspection Pg 2 {2} {3}.pdf", year, techId, store, date);
string directory = string.Format(#"C:\Documents\{0}\{1}", year, techId);
templateReader = new PdfReader(template);
//Check for directory and create if doesn't exist
if (!Directory.Exists(directory))
Directory.CreateDirectory(directory);
templateStamper = new PdfStamper(templateReader, new FileStream(newFile, FileMode.Create));
AcroFields templateFields = templateStamper.AcroFields;
AcroFields overFlowFields = null;
int equipCnt = 1;
int attachCnt = 1;
//Extract stand alone items from equipment list
List<CPEquipment> seUnits = (from s in equipment
where s.Serial == s.AttachedTo && s.Status != "ATTACHMENT"
select s).ToList();
//Extract attachments from equipment list
List<CPEquipment> attachments = (from a in equipment
where a.Status == "ATTACHMENT"
select a).ToList();
//Set header and footer info in new file
templateFields.SetField("Store Number", store);
templateFields.SetField("Technician", techId);
templateFields.SetField("Week Of", date.WeekOf());
templateFields.SetField("Street Address", stAddress);
templateFields.SetField("City", stCity);
templateFields.SetField("Comments", header.Comments + "\nTrained:\t" + header.Trained + "\nOn:\t" + header.Topics);
templateFields.SetField("Footer", footerText);
//Set security info in new file
templateFields.SetField("WL", header.WL == "True" ? "Yes" : "No");
templateFields.SetField("TL", header.TL == "True" ? "Yes" : "No");
templateFields.SetField("CC", header.CC == "True" ? "Yes" : "No");
//Set equipment lines in new file
int maxLines = seUnits.Count > 20 ? 20 : seUnits.Count;
while (equipCnt <= maxLines)
{
CPEquipment current = seUnits.ElementAt(equipCnt - 1);
CPEquipment trailer = (from t in equipment
where t.AttachedTo == current.Serial && t.AttachedTo != t.Serial && t.Status != "ATTACHMENT"
select t).FirstOrDefault();
templateFields.SetField("ModelRow" + equipCnt, current.Model);
templateFields.SetField("SerialRow" + equipCnt, current.Serial);
templateFields.SetField("StatusRow" + equipCnt, current.Status);
templateFields.SetField("Tool TurnedRow" + equipCnt, current.ToolTurned);
templateFields.SetField("Last PMRow" + equipCnt, current.LastPmDate + " " + current.LastPmHours);
templateFields.SetField("Current HoursRow" + equipCnt, current.CurrentHours);
templateFields.SetField("TagRow" + equipCnt, current.Tag);
templateFields.SetField("StExpiresRow" + equipCnt, current.State + " " + current.Expiration);
if (trailer != null)
{
templateFields.SetField("Trailer ModelRow" + equipCnt, trailer.Serial);
templateFields.SetField("Trailer VINRow" + equipCnt, trailer.Model);
templateFields.SetField("TagRow" + equipCnt, trailer.Tag);
templateFields.SetField("StExpiresRow" + equipCnt, trailer.State + " " + trailer.Expiration);
}
equipCnt++;
}
//Set overflow lines if any
if (seUnits.Count > 20)
{
overFlowReader = new PdfReader(overflowTemplate);
overFlowStamper = new PdfStamper(overFlowReader, new FileStream(overFlowFile, FileMode.Create));
overFlowFields = overFlowStamper.AcroFields;
overFlowFields.SetField("Store", store);
overFlowFields.SetField("Footer", footerText);
while (equipCnt > 20 && equipCnt < seUnits.Count)
{
CPEquipment current = seUnits.ElementAt(equipCnt - 1);
CPEquipment trailer = (from t in equipment
where t.AttachedTo == current.Serial && t.AttachedTo != t.Serial
select t).FirstOrDefault();
overFlowFields.SetField("ModelRow" + (equipCnt - 20), current.Model);
overFlowFields.SetField("SerialRow" + (equipCnt - 20), current.Serial);
overFlowFields.SetField("StatusRow" + (equipCnt - 20), current.Status);
overFlowFields.SetField("Tool TurnedRow" + (equipCnt - 20), current.ToolTurned);
overFlowFields.SetField("Last PMRow" + (equipCnt - 20),
current.LastPmDate + " " + current.LastPmHours);
overFlowFields.SetField("Current HoursRow" + (equipCnt - 20), current.CurrentHours);
overFlowFields.SetField("TagRow" + (equipCnt - 20), current.Tag);
overFlowFields.SetField("StExpiresRow" + (equipCnt - 20),
current.State + " " + current.Expiration);
if (trailer != null)
{
overFlowFields.SetField("Trailer ModelRow" + (equipCnt - 20), trailer.Serial);
overFlowFields.SetField("Trailer VINRow" + (equipCnt - 20), trailer.Model);
overFlowFields.SetField("TagRow" + (equipCnt - 20), trailer.Tag);
overFlowFields.SetField("StExpiresRow" + (equipCnt - 20),
trailer.State + " " + trailer.Expiration);
}
equipCnt++;
}
overFlowStamper.FormFlattening = true;
overFlowReader.Close();
overFlowStamper.Close();
}
//Set attachment fields and update attachment in db
foreach (CPEquipment attach in attachments)
{
templateFields.SetField("SNRow" + attachCnt, attach.Serial);
templateFields.SetField("MR" + attachCnt, attach.Model);
attachCnt++;
}
//Flatten forms and close readers and stampers
templateStamper.FormFlattening = true;
templateReader.Close();
templateStamper.Close();
//Set up email
MailMessage mail = new MailMessage(new MailAddress("me#mydomain.com"),
new MailAddress(techMail));
mail.Attachments.Add(new Attachment(newFile));
if (equipCnt > 20)
mail.Attachments.Add(new Attachment(overFlowFile));
mail.Subject = "Weekly Inspection";
SmtpClient client = new SmtpClient(//Hidden);
client.Send(mail);
return result;
}
catch (Exception e)
{
if (templateStamper != null)
{
templateStamper.FormFlattening = true;
templateStamper.Close();
}
if (overFlowStamper != null)
{
overFlowStamper.FormFlattening = true;
overFlowStamper.Close();
}
if (templateReader != null)
templateReader.Close();
if (overFlowReader != null)
overFlowReader.Close();
return "Submit Weekly: " + e.Message;
}
}
A using Statement with the PdfStamper and FileStream should solve your problem. If you don't need to save the PDF(s), you can replace FileStream with a MemoryStream to save you the extra step of deleting the file(s) after sending the email attachments.