I am generating a multiple page PDF using ITextSharp, each page having the sames template.
The problem is that the PDF grows in Phisical Size by the size of the template.
I HAVE to use ACROFIELDS.
How can I reduce the final file size ?
Here is a code snippet of the pdf handler:
public void ProcessRequest(HttpContext context)
{
Context = context;
Response = context.Response;
Request = context.Request;
try
{
LoadDataInternal();
}
catch (System.Threading.ThreadAbortException)
{
// no-op
}
catch (Exception ex)
{
Logger.LogError(ex);
Response.Write("Error");
Response.End();
}
Response.BufferOutput = true;
Response.ClearHeaders();
Response.ContentType = "application/pdf";
if (true)
{
Response.AddHeader("Content-Disposition", "attachment; filename=" +
(string.IsNullOrEmpty(DownloadFileName) ? context.Session.SessionID + ".pdf" : DownloadFileName));
}
PdfCopyFields copy
= new PdfCopyFields(Response.OutputStream);
// add a document
for (int i = 0; i < dataset.Tables["Model"].Rows.Count; i++)
{
copy.AddDocument(new PdfReader(renameFieldsIn(TemplatePath, i)));
// add a document
}
copy.SetFullCompression();
// Close the PdfCopyFields object
copy.Close();
}
private byte[] renameFieldsIn(String datasheet, int i)
{
MemoryStream baos = new MemoryStream();
// Create the stamper
PdfStamper stamper = new PdfStamper(new PdfReader(GetTemplateBytes()), baos);
// Get the fields
AcroFields form = stamper.AcroFields;
// Loop over the fields
List<String> keys = new List<String>(form.Fields.Keys);
foreach (var key in keys)
{
// rename the fields
form.RenameField(key, String.Format("{0}_{1}", key, i));
}
stamper.FormFlattening = true;
stamper.FreeTextFlattening = true;
stamper.SetFullCompression();
SetFieldsInternal(form, i);
// close the stamper
stamper.Close();
return baos.ToArray();
}
protected byte[] GetTemplateBytes()
{
var data = Context.Cache[PdfTemplateCacheKey] as byte[];
if (data == null)
{
data = File.ReadAllBytes(Context.Server.MapPath(TemplatePath));
Context.Cache.Insert(PdfTemplateCacheKey, data,
null, DateTime.Now.Add(PdfTemplateCacheDuration), Cache.NoSlidingExpiration);
}
return data;
}
I have done something a little similar before and found that after combining all the pages, running the entire generated document through the PDFStamper again resulted in a noticeable compression of the file size.
Ok, so a friend of mine came up with a solution. The only problem remaining is the amount of memory it takes to create a new PdfStamper. So here's the rewritten procedure.
Anyway. Hope this hepls anyone else. And if you have a better solution please don't be shy.
public void ProcessRequest (HttpContext context)
{
var watch = System.Diagnostics.Stopwatch.StartNew();
Context = context;
Response = context.Response;
Request = context.Request;
Response.BufferOutput = true;
Response.ClearHeaders();
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment; filename=itextsharp_multiple.pdf");
var pageBytes = (byte[])null;
var pagesAll = new List<byte[]>();
try
{
for (int i = 0; i < GlobalHttpApplication.Model.TestData.Rows.Count; i++)
{
PdfStamper pst = null;
MemoryStream mstr = null;
using (mstr = new MemoryStream())
{
try
{
PdfReader reader = new PdfReader(GetTemplateBytes());
pst = new PdfStamper(reader, mstr);
var acroFields = pst.AcroFields;
SetFieldsInternal(acroFields, 0);
pst.FormFlattening = true;
pst.SetFullCompression();
} finally
{
if (pst != null)
pst.Close();
}
}
pageBytes = mstr.ToArray();
pagesAll.Add(pageBytes);
}
} finally
{
}
Document doc = new Document(PageSize.A4);
var writer = PdfWriter.GetInstance(doc, Response.OutputStream);
var copy2 = new PdfSmartCopy(doc, Response.OutputStream);
doc.Open();
doc.OpenDocument();
foreach (var b in pagesAll)
{
doc.NewPage();
copy2.AddPage(copy2.GetImportedPage(new PdfReader(b), 1));
}
copy2.Close();
watch.Stop();
File.AppendAllText(context.Server.MapPath("~/App_Data/log.txt"), watch.Elapsed + Environment.NewLine);
}
Related
I'm trying to insert an image with id into a PDF document and allow to replace it later with another image.
My process is as follows:
Get an image from the client (with a unique ID).
Try to find an existing image with the same ID, in the PDF document.
If I find an existing image, try to delete it and put the new image instead, or try to replace the existing image with the new one. (tried both).
If I don't find an existing image, insert the image in a position I choose.
I use code from Bruno Lowagie book:
Replacing
Adding image
The problem is that whenever I delete an existing image or replace it my document gets corrupted. What am I doing wrong?
This is the code:
public static bool PdfInsertSignature(string path, string fileName, string signatureName, byte[] imageBytes)
{
bool resultOk = true;
string tmpFilename = string.Concat("tmp_", Guid.NewGuid().ToString(), ".pdf");
// get file, copy to new file with signature
using (Stream inputPdfStream = new FileStream(path + fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
using (Stream outputPdfStream = new FileStream(path + tmpFilename, FileMode.Create, FileAccess.Write, FileShare.None))
{
using (var reader = new PdfReader(inputPdfStream))
using (PdfStamper stamper = new PdfStamper(reader, outputPdfStream, '\0', false))
{
var img = System.Drawing.Image.FromStream(new MemoryStream(imageBytes));
Image image = Image.GetInstance(img, BaseColor.WHITE);
img.Dispose();
var positions = stamper.AcroFields.GetFieldPositions(signatureName)[0];
if (positions != null)
{
//DeleteExistingSignatureImage(reader, stamper, signatureName);
image.SetAbsolutePosition(positions.position.Left + 20, positions.position.Top - 15);
image.ScalePercent(0.2f * 100);
image.BorderWidth = 0;
PdfImage pdfImg = new PdfImage(image, "", null);
pdfImg.Put(new PdfName("ITXT_SigImageId"), new PdfName(signatureName + "_img"));
if (!ReplaceImage(reader, stamper, signatureName, pdfImg))
{
PdfIndirectObject objRef = stamper.Writer.AddToBody(pdfImg);
image.DirectReference = objRef.IndirectReference;
PdfContentByte pdfContentByte = stamper.GetOverContent(positions.page);
pdfContentByte.AddImage(image);
}
}
else
{
resultOk = false;
logger.Error($"No matching Signature found for signatureName: {signatureName} in fileName: {fileName}.");
}
}
}
if (resultOk)
{
// delete old file and rename new file to old file's name
File.Delete(path + fileName);
File.Move(path + tmpFilename, path + fileName);
}
else
{
File.Delete(path + tmpFilename);
}
return resultOk;
}
private static bool ReplaceImage(PdfReader reader, PdfStamper stamper, string signatureName, PdfStream newImgStream)
{
PdfName key = new PdfName("ITXT_SigImageId");
PdfName value = new PdfName(signatureName + "_img");
PdfObject obj;
PRStream stream;
for (int i = 1; i < reader.XrefSize; i++)
{
obj = reader.GetPdfObject(i);
if (obj == null || !obj.IsStream())
{
continue;
}
stream = (PRStream)obj;
PdfObject pdfSubtype = stream.Get(PdfName.SUBTYPE);
if (pdfSubtype != null && pdfSubtype.ToString().Equals(PdfName.IMAGE.ToString()))
{
var streamVal = stream.Get(key);
if (streamVal != null && value.Equals(streamVal))
{
stream.Clear();
var ms = new MemoryStream();
stream.WriteContent(ms);
stream.SetData(ms.ToArray(), false);
foreach (PdfName name in newImgStream.Keys)
{
stream.Put(name, stream.Get(name));
}
return true;
}
}
}
return false;
}
private static void DeleteExistingSignatureImage(PdfReader reader, PdfStamper stamper, string signatureName)
{
PdfName key = new PdfName("ITXT_SigImageId");
PdfName value = new PdfName(signatureName + "_img");
PdfObject obj;
PRStream stream;
for (int i = 1; i < reader.XrefSize; i++)
{
obj = reader.GetPdfObject(i);
if (obj == null || !obj.IsStream())
{
continue;
}
stream = (PRStream)obj;
PdfObject pdfSubtype = stream.Get(PdfName.SUBTYPE);
if (pdfSubtype != null && pdfSubtype.ToString().Equals(PdfName.IMAGE.ToString()))
{
var streamVal = stream.Get(key);
if (streamVal != null && value.Equals(streamVal))
{
stream.Clear();
PdfReader.KillIndirect(stream);
//PdfReader.KillIndirect(obj);
//reader.RemoveUnusedObjects();
}
}
}
}
The purpose of signing a PDF file is to prevent further changes without notice.
You need to sign the document after you swap the image, or it will be corrupted.
Just do make it easier to find:
This is Solution provided by amira.
This is the code i've used to replace a 'ButtonField' on my PDF template with a signature image :
string TempStampPath = Server.MapPath(TempPath + "BookingConfirmation.pdf");
PdfReader pdfReader = new PdfReader(TempStampPath);
PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(LocalFileName, FileMode.Create));
AcroFields pdfFormFields = pdfStamper.AcroFields;
try
{
pdfFormFields.SetField("NameSurname", NameSurname);
pdfFormFields.SetField("IdNumber", IDNumber);
pdfFormFields.SetField("CourseName", CourseName);
pdfFormFields.SetField("Location", Venue);
pdfFormFields.SetField("DateCompleted", CourseDate);
pdfFormFields.SetField("FacilitatorName", Facilitator);
try
{
iTextSharp.text.Image signature = iTextSharp.text.Image.GetInstance(image, System.Drawing.Imaging.ImageFormat.Png);
PushbuttonField ad = pdfStamper.AcroFields.GetNewPushbuttonFromField("btnFacilitatorSignature");
ad.Layout = PushbuttonField.LAYOUT_ICON_ONLY;
ad.ProportionalIcon = true;
ad.Image = signature;
ad.BackgroundColor = iTextSharp.text.BaseColor.WHITE;
pdfFormFields.ReplacePushbuttonField("btnFacilitatorSignature", ad.Field);
}
catch (Exception ex)
{ }
pdfStamper.FormFlattening = true;
pdfStamper.Close();
pdfStamper.Dispose();
pdfReader.Close();
}
catch (Exception ex)
{
pdfStamper.Close();
pdfStamper.Dispose();
pdfReader.Close();
}
when i am trying the merge the PDF's in C# using itextsharp, i used below code It worked for 2 or 3 times. But after that Output file is creating with 0 kb, when i am trying open file it showing file is in use or already open by other. Please help if missed anything Thanks in Adavance.
iTextSharp.text.pdf.PdfReader reader = null;
PdfImportedPage page = null;
FileStream stream = null;
Document pdfDoc = null;
try
{
using(pdfDoc = new Document())
stream = new FileStream(targetPDF, FileMode.Create);
{
using (PdfCopy pdf = new PdfCopy(pdfDoc, stream))
{
pdfDoc.Open();
var files = Directory.GetFiles(sourceDir);
foreach (string file in files)
{
reader = new iTextSharp.text.pdf.PdfReader(file);
for (int i = 0; i < reader.NumberOfPages; i++)
{
page = pdf.GetImportedPage(reader, i + 1);
pdf.AddPage(page);
}
pdf.FreeReader(reader);
reader.Close();
}
}
}
}
catch (Exception ex)
{
if (reader != null)
{
reader.Close();
}
}
enter image description here
I don't know what happen with your code but I can give a function (I'm using in my project working 100%) that merge a list of file
private bool MergePDFs(IEnumerable<string> fileNames, string targetPdf)
{
bool merged = true;
using (FileStream stream = new FileStream(targetPdf, FileMode.Create))
{
Document document = new Document();
PdfCopy pdf = new PdfCopy(document, stream);
PdfReader reader = null;
try
{
document.Open();
foreach (string file in fileNames)
{
System.Threading.Thread.Sleep(1500);
reader = new PdfReader(file);
pdf.AddDocument(reader);
reader.Close();
}
}
catch (Exception)
{
merged = false;
if (reader != null)
{
reader.Close();
}
}
finally
{
if (document != null)
{
document.Close();
}
}
}
return merged;
}
so for fileNames : you give the list of your files (construct a list
from your folder by listing files)
targetPdf is the outPut file name
I'm trying to merge several PDFs into a single file through a list that contains their content in byte[]. When opening a document from the Byte[] list with PdfReader, the program launches the following exception: "the document has no pages". When I review the contents of the Byte[] list there are complete, but the exception is always launched.
I try to download the content of that single page separately and the generated document launches error when opening it. The division of the pdf does well because it generates each document in physical and makes it perfect for each page of the PDF.
I appreciate your help or opinions in this situation.
This is the code I use to split and merge documents:
public List<byte[]> SplitPDF(byte[] contentPdf)
{
try
{
var listBythe = new List<byte[]>();
PdfImportedPage page = null;
PdfCopy PdfCopy = null;
PdfReader reader = new PdfReader(contentPdf);
for (int numPage = 1; numPage <= reader.NumberOfPages; numPage++)
{
Document doc = new Document(PageSize.LETTER);
var mStream = new MemoryStream();
PdfCopy = new PdfCopy(doc, mStream);
doc.Open();
page = PdfCopy.GetImportedPage(reader, numPage);
PdfCopy.AddPage(page);
listBythe.Add(mStream.ToArray());
doc.Close();
}
MergePdfToPage(listBythe);
return listBythe;
}
catch (Exception ex)
{
throw ex;
}
}
private byte[] MergePdfToPage(List<byte[]>contentPage)
{
byte[] docPdfByte = null;
var ms = new MemoryStream();
using (Document doc = new Document(PageSize.LETTER))
{
PdfCopy copy = new PdfCopy(doc, ms);
doc.Open();
var num = doc.PageNumber;
foreach (var file in contentPage.ToArray())
{
using (var reader = new PdfReader(file))
{
copy.AddDocument(reader);
}
}
doc.Close();
docPdfByte = ms.ToArray();
}
return docPdfByte;
In your loop you do
Document doc = new Document(PageSize.LETTER);
var mStream = new MemoryStream();
PdfCopy = new PdfCopy(doc, mStream);
doc.Open();
page = PdfCopy.GetImportedPage(reader, numPage);
PdfCopy.AddPage(page);
listBythe.Add(mStream.ToArray());
doc.Close();
In particular you retrieve the mStream bytes before closing doc. But before doc is closed, the pdf is incomplete in mStream!
To get a complete pdf from mStream, please change the order of instructions an do
Document doc = new Document(PageSize.LETTER);
var mStream = new MemoryStream();
PdfCopy = new PdfCopy(doc, mStream);
doc.Open();
page = PdfCopy.GetImportedPage(reader, numPage);
PdfCopy.AddPage(page);
doc.Close();
listBythe.Add(mStream.ToArray());
instead.
I created something for you, hopefully it will work as well as it did for me.
Class :
public class PDFFactory
{
public PDFFactory()
{
PdfDocument = new Document(iTextSharp.text.PageSize.A4, 65, 65, 60, 60);
}
private Document _pdfDocument;
public Document PdfDocument
{
get
{
return _pdfDocument;
}
set
{
_pdfDocument = value;
}
}
private MemoryStream _pdfMemoryStream;
public MemoryStream PDFMemoryStream
{
get
{
return _pdfMemoryStream;
}
set
{
_pdfMemoryStream = value;
}
}
private string _pdfBase64;
public string PDFBase64
{
get
{
if (this.DocumentClosed)
return _pdfBase64;
else
return null;
}
set
{
_pdfBase64 = value;
}
}
private byte[] _pdfBytes;
public byte[] PDFBytes
{
get
{
if (this.DocumentClosed)
return _pdfBytes;
else
return null;
}
set
{
_pdfBytes = value;
}
}
public byte[] GetPDFBytes()
{
PDFDocument.Close();
return PDFMemoryStream.GetBuffer();
}
public void closeDocument()
{
PDFDocument.Close();
PDFBase64 = Convert.ToBase64String(this.PDFMemoryStream.GetBuffer());
PDFBytes = this.PDFMemoryStream.GetBuffer();
}
}
Service:
public byte[] ()
{
PDFFactory pdf_1 = new PDFFactory();
PDFFactory pdf_2 = new PDFFactory();
List<byte[]> sourceFiles = new List<byte[]>();
sourceFiles.Add(pdf_1.GetPDFBytes);
sourceFiles.Add(pdf_2.GetPDFBytes);
PDFFactory pdfFinal = new PDFFactory();
for (int fileCounter = 0; fileCounter <= sourceFiles.Count - 1; fileCounter += 1)
{
PdfReader reader2 = new PdfReader(sourceFiles[fileCounter]);
int numberOfPages = reader2.NumberOfPages;
for (int currentPageIndex = 1; currentPageIndex <= numberOfPages; currentPageIndex++)
{
// Determine page size for the current page
pdfFinal.PDFDocument.SetPageSize(reader2.GetPageSizeWithRotation(currentPageIndex));
// Create page
pdfFinal.PDFDocument.NewPage();
PdfImportedPage importedPage = pdfFinal.PDFWriter.GetImportedPage(reader2, currentPageIndex);
// Determine page orientation
int pageOrientation = reader2.GetPageRotation(currentPageIndex);
if ((pageOrientation == 90) || (pageOrientation == 270))
pdfFinal.PDFWriter.DirectContent.AddTemplate(importedPage, 0, -1.0F, 1.0F, 0, 0, reader2.GetPageSizeWithRotation(currentPageIndex).Height);
else
pdfFinal.PDFWriter.DirectContent.AddTemplate(importedPage, 1.0F, 0, 0, 1.0F, 0, 0);
}
}
pdfFinal.closeDocument();
return pdfFinal.PDFBytes;
}
Let me know if it helped.
I am building an app that modifies a word 2010 document and it should be downloaded as pdf.I write a code to convert word to pdf but it is converting the document I upload not the modified word. How can I convert modified word to PDF.Below is the function which is not converting modified word.
protected void btnUpload_Click(object sender, EventArgs e)
{
if (FileUploadControl.HasFile)
{
string fileNameFromUser = FileUploadControl.FileName;
var fiFileName = new System.IO.FileInfo(fileNameFromUser);
using (MemoryStream ms = new MemoryStream())
{
ms.Write(FileUploadControl.FileBytes, 0, FileUploadControl.FileBytes.Length);
using (WordprocessingDocument sDoc = WordprocessingDocument.Open(ms, true))
{
}
lblMessage.Text = "Dokumenti u ngarkua me sukses!";
Session["ByteArray"] = FileUploadControl.FileBytes;
Session["fileNameFromUser"] = fileNameFromUser;
}
}
byte[] byteArray = (byte[])(Session["ByteArray"]);
if (byteArray != null)
{
try
{
using (MemoryStream ms = new MemoryStream())
{
ms.Write(byteArray, 0, byteArray.Length);
using (WordprocessingDocument wDoc = WordprocessingDocument.Open(ms, true))
{
var body = wDoc.MainDocumentPart.Document.Body;
var lastParagraf = body.Elements<Paragraph>().LastOrDefault();
var newParagraf = new Paragraph(
new Run(
new Text("Perdoruesi:" + " " + User.Identity.Name)));
var newParagraf2 = new Paragraph(
new Run(
new Text("Data dhe ora:" + " " + DateTime.Now.ToString())));
var newParagraf3 = new Paragraph(
new Run(
new Text("Kodi unik:" + " " + randomstring(14))));
var newParagraf4 = new Paragraph(
new Run(
new Text("Shifra:" )));
lastParagraf.InsertAfterSelf(newParagraf);
lastParagraf.InsertAfterSelf(newParagraf2);
lastParagraf.InsertAfterSelf(newParagraf3);
lastParagraf.InsertAfterSelf(newParagraf4);
}
Session["ByteArray"] = ms.ToArray();
lblMessage.Text = "U ngarkua dhe u vulos dokumenti!";
Guid pdfFileGuid = Guid.NewGuid();
var filePath = Path.GetTempFileName();
FileUploadControl.SaveAs(filePath);
var appWord = new Microsoft.Office.Interop.Word.Application();
var wordDoc = appWord.Documents.Open(filePath);
var convertedFilePath = Path.GetTempFileName();
wordDoc.ExportAsFixedFormat(convertedFilePath, Microsoft.Office.Interop.Word.WdExportFormat.wdExportFormatPDF);
Response.Clear();
Response.AddHeader("content-disposition", "attachment; filename=Converted.Pdf");
Response.AddHeader("content-type", "application/pdf");
Response.TransmitFile(convertedFilePath);
File.Delete(filePath);
File.Delete(convertedFilePath);
}
}
catch (Exception ex)
{
lblMessage.Text = "ERROR:" + ex.Message.ToString();
}
}
else
{
lblMessage.Text = "Nuk e keni zgjedhur dokumentin apo formati i dokumentit nuk pershtatet!";
}
}
Currently, here you load the data from the FileUploadControl into session:
Session["ByteArray"] = FileUploadControl.FileBytes;
You then load the data from session into a MemoryStream that you use to open the document for editing:
byte[] byteArray = (byte[])(Session["ByteArray"]);
if (byteArray != null)
{
try
{
using (MemoryStream ms = new MemoryStream())
{
ms.Write(byteArray, 0, byteArray.Length);
using (WordprocessingDocument wDoc = WordprocessingDocument.Open(ms, true))
At the end of this, after your edits, you copy the updated content back to session:
lastParagraf.InsertAfterSelf(newParagraf3);
lastParagraf.InsertAfterSelf(newParagraf4);
}
Session["ByteArray"] = ms.ToArray();
but; that's the last time we see session used; you then write the uploaded file to a temporary file, and use that to perform Word automation:
var filePath = Path.GetTempFileName();
FileUploadControl.SaveAs(filePath);
var appWord = new Microsoft.Office.Interop.Word.Application();
var wordDoc = appWord.Documents.Open(filePath);
So yes: this will convert the original file as uploaded, because FileUploadControl is unrelated to the changes you made. Instead, perhaps try:
var filePath = Path.GetTempFileName();
File.WriteAllBytes(filePath, (byte[])Session["ByteArray"]);
var appWord = new Microsoft.Office.Interop.Word.Application();
var wordDoc = appWord.Documents.Open(filePath);
This should then include the changes.
Additional side observations:
Word automation is unsupported and not recommended on web-servers; if it works for you: great, but just be aware that if it suddenly breaks you'll be on your own
be careful that you're not leaving files scattered on disk, or lots of open Word instances / files; basically: check you're not "leaking" (appWord, wordDoc, filePath, convertedFilePath etc - all probably need some finally love)
putting Word files into session-state (Session) probably isn't a good or necessary idea; I would recommend just using a local byte[] or similar throughout in this method, and remove Session["ByteArray"] completely
How do one create PDF in memorystream instead of physical file using itext7?
I have no idea how to do it in the latest version, any help?
I tried the following code, but pdfSM is not properly populated:
string filePath = "./abc.pdf";
MemoryStream pdfSM = new ByteArrayOutputStream();
PdfDocument doc = new PdfDocument(new PdfReader(filePath), new PdfWriter(pdfSM));
.......
doc.close();
The full testing code as below for your reference, it worked when past filePath into PdfWriter but not for the memory stream:
public static readonly String sourceFolder = "../../FormTest/";
public static readonly String destinationFolder = "../../Output/";
static void Main(string[] args)
{
String srcFilePattern = "I-983";
String destPattern = "I-129_2014_";
String src = sourceFolder + srcFilePattern + ".pdf";
String dest = destinationFolder + destPattern + "_flattened.pdf";
MemoryStream returnSM = new MemoryStream();
PdfDocument doc = new PdfDocument(new PdfReader(src), new PdfWriter(returnSM));
PdfAcroForm form = PdfAcroForm.GetAcroForm(doc, false);
foreach (PdfFormField field in form.GetFormFields().Values)
{
var fieldName = field.GetFieldName();
var type = field.GetType();
if (fieldName != null)
{
if (type.Name.Equals("PdfTextFormField"))
{
field.SetValue("T");
}
}
}
form.FlattenFields();
doc.Close();
}
This works for me.
public byte[] CreatePdf()
{
var stream = new MemoryStream();
var writer = new PdfWriter(stream);
var pdf = new PdfDocument(writer);
var document = new Document(pdf);
document.Add(new Paragraph("Hello world!"));
document.Close();
return stream.ToArray();
}
I needed the same thing. Got it working like this:
(I included some settings which improve performance)
string HtmlString = "<html><head></head><body>some content</body></html>";
byte[] buffer;
PdfDocument pdfDoc = null;
using (MemoryStream memStream = new MemoryStream())
{
using(PdfWriter pdfWriter = new PdfWriter(memStream, wp))
{
pdfWriter.SetCloseStream(true);
using (pdfDoc = new PdfDocument(pdfWriter))
{
ConverterProperties props = new ConverterProperties();
pdfDoc.SetDefaultPageSize(PageSize.LETTER);
pdfDoc.SetCloseWriter(true);
pdfDoc.SetCloseReader(true);
pdfDoc.SetFlushUnusedObjects(true);
HtmlConverter.ConvertToPdf(HtmlString, pdfDoc, props));
pdfDoc.Close();
}
}
buffer = memStream.ToArray();
}
return buffer;
iText7、C# Controller
Error:
public ActionResult Report()
{
//...
doc1.Close();
return File(memoryStream1, "application/pdf", "pdf_file_name.pdf");
}
Work:
public ActionResult Report()
{
//...
doc1.Close();
byte[] byte1 = memoryStream1.ToArray();
return File(byte1, "application/pdf", "pdf_file_name.pdf");
}
I don't know why... but, it's working!
another: link