У меня есть этот демо-код для iTextSharp
Document document = new Document();
try
{
PdfWriter.GetInstance(document, new FileStream("Chap0101.pdf", FileMode.Create));
document.Open();
document.Add(new Paragraph("Hello World"));
}
catch (DocumentException de)
{
Console.Error.WriteLine(de.Message);
}
catch (IOException ioe)
{
Console.Error.WriteLine(ioe.Message);
}
document.Close();
Как мне заставить контроллер вернуть документ PDF в браузер?
EDIT:
Запуск этого кода открывает Acrobat, но появляется сообщение об ошибке "Файл поврежден и не может быть восстановлен"
public FileStreamResult pdf()
{
MemoryStream m = new MemoryStream();
Document document = new Document();
PdfWriter.GetInstance(document, m);
document.Open();
document.Add(new Paragraph("Hello World"));
document.Add(new Paragraph(DateTime.Now.ToString()));
m.Position = 0;
return File(m, "application/pdf");
}
Любые идеи, почему это не работает?
Я работал с этим кодом.
using iTextSharp.text;
using iTextSharp.text.pdf;
public FileStreamResult pdf()
{
MemoryStream workStream = new MemoryStream();
Document document = new Document();
PdfWriter.GetInstance(document, workStream).CloseStream = false;
document.Open();
document.Add(new Paragraph("Hello World"));
document.Add(new Paragraph(DateTime.Now.ToString()));
document.Close();
byte[] byteInfo = workStream.ToArray();
workStream.Write(byteInfo, 0, byteInfo.Length);
workStream.Position = 0;
return new FileStreamResult(workStream, "application/pdf");
}
Вернуть a FileContentResult
. Последняя строка в действии вашего контроллера будет выглядеть примерно так:
return File("Chap0101.pdf", "application/pdf");
Если вы создаете этот PDF файл динамически, лучше использовать MemoryStream
и создать документ в памяти вместо сохранения в файл. Код будет примерно таким:
Document document = new Document();
MemoryStream stream = new MemoryStream();
try
{
PdfWriter pdfWriter = PdfWriter.GetInstance(document, stream);
pdfWriter.CloseStream = false;
document.Open();
document.Add(new Paragraph("Hello World"));
}
catch (DocumentException de)
{
Console.Error.WriteLine(de.Message);
}
catch (IOException ioe)
{
Console.Error.WriteLine(ioe.Message);
}
document.Close();
stream.Flush(); //Always catches me out
stream.Position = 0; //Not sure if this is required
return File(stream, "application/pdf", "DownloadName.pdf");
Если вы возвращаете FileResult
из своего метода действий и используете метод расширения File()
на контроллере, делать то, что вы хотите, довольно легко. В методе File()
есть переопределения, которые будут принимать двоичное содержимое файла, путь к файлу или Stream
.
public FileResult DownloadFile()
{
return File("path\\to\\pdf.pdf", "application/pdf");
}
Вы должны указать:
Response.AppendHeader("content-disposition", "inline; filename=file.pdf");
return new FileStreamResult(stream, "application/pdf")
Для того, чтобы файл открывался напрямую в браузере вместо загружался
У меня возникли аналогичные проблемы, и я наткнулся на решение. Я использовал два сообщения, один из stack, в котором показан метод возврата для загрузки, а другой один, который показывает рабочее решение для ItextSharp и MVC.
public FileStreamResult About()
{
// Set up the document and the MS to write it to and create the PDF writer instance
MemoryStream ms = new MemoryStream();
Document document = new Document(PageSize.A4.Rotate());
PdfWriter writer = PdfWriter.GetInstance(document, ms);
// Open the PDF document
document.Open();
// Set up fonts used in the document
Font font_heading_1 = FontFactory.GetFont(FontFactory.TIMES_ROMAN, 19, Font.BOLD);
Font font_body = FontFactory.GetFont(FontFactory.TIMES_ROMAN, 9);
// Create the heading paragraph with the headig font
Paragraph paragraph;
paragraph = new Paragraph("Hello world!", font_heading_1);
// Add a horizontal line below the headig text and add it to the paragraph
iTextSharp.text.pdf.draw.VerticalPositionMark seperator = new iTextSharp.text.pdf.draw.LineSeparator();
seperator.Offset = -6f;
paragraph.Add(seperator);
// Add paragraph to document
document.Add(paragraph);
// Close the PDF document
document.Close();
// Hat tip to David for his code on stackoverflow for this bit
// /questions/58521/aspnet-mvc-how-to-get-view-to-generate-pdf
byte[] file = ms.ToArray();
MemoryStream output = new MemoryStream();
output.Write(file, 0, file.Length);
output.Position = 0;
HttpContext.Response.AddHeader("content-disposition","attachment; filename=form.pdf");
// Return the output stream
return File(output, "application/pdf"); //new FileStreamResult(output, "application/pdf");
}
Я знаю, что этот вопрос старый, но я думал, что поделюсь этим, потому что не мог найти ничего подобного.
Я хотел создать свои представления/модели как обычные с помощью Razor и сделать их представленными как Pdfs.
Таким образом, я контролировал презентацию pdf с использованием стандартного вывода html, а не выяснял, как развернуть документ с помощью iTextSharp.
Проект и исходный код доступны здесь с инструкциями по установке nuget:
https://github.com/andyhutch77/MvcRazorToPdf
Install-Package MvcRazorToPdf
Вы можете создать собственный класс, чтобы изменить тип содержимого и добавить файл в ответ.
Обычно вы делаете Response.Flush, за которым следует Response.Close, но по какой-то причине библиотека iTextSharp, похоже, не нравится. Данные не проходят, и Adobe думает, что PDF файл поврежден. Оставьте функцию Response.Close и посмотрите, улучшены ли ваши результаты:
Response.Clear();
Response.ContentType = "application/pdf";
Response.AppendHeader("Content-disposition", "attachment; filename=file.pdf"); // open in a new window
Response.OutputStream.Write(outStream.GetBuffer(), 0, outStream.GetBuffer().Length);
Response.Flush();
// For some reason, if we close the Response stream, the PDF doesn't make it through
//Response.Close();
если вы возвращаете var-двоичные данные из БД для отображения PDF на всплывающем или браузере, следуйте этому коду: -
Страница просмотра:
@using (Html.BeginForm("DisplayPDF", "Scan", FormMethod.Post))
{
<a href="javascript:;" onclick="document.forms[0].submit();">View PDF</a>
}
Контроллер сканирования:
public ActionResult DisplayPDF()
{
byte[] byteArray = GetPdfFromDB(4);
MemoryStream pdfStream = new MemoryStream();
pdfStream.Write(byteArray, 0, byteArray.Length);
pdfStream.Position = 0;
return new FileStreamResult(pdfStream, "application/pdf");
}
private byte[] GetPdfFromDB(int id)
{
#region
byte[] bytes = { };
string constr = System.Configuration.ConfigurationManager.ConnectionStrings["Connection"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = "SELECT Scan_Pdf_File FROM PWF_InvoiceMain WHERE InvoiceID=@Id and Enabled = 1";
cmd.Parameters.AddWithValue("@Id", id);
cmd.Connection = con;
con.Open();
using (SqlDataReader sdr = cmd.ExecuteReader())
{
if (sdr.HasRows == true)
{
sdr.Read();
bytes = (byte[])sdr["Scan_Pdf_File"];
}
}
con.Close();
}
}
return bytes;
#endregion
}