2009-10-02 2 views
100

У меня есть этот демонстрационный код для iTextSharpКак вернуть PDF в браузер в MVC?

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"); 
    } 

Любые идеи, почему это не работает?

+0

- проверить out http://www.nyveldt.com/blog/post/Introducing-RazorPDF – mg1075

+0

@ mg1075 ваша ссылка мертва – thecoolmacdude

+0

@thecoolmacdude - ok ... http://nyveldt.com/blog/page/razorpdf; http://nyveldt.com/blog/post/razorpdf-samples; https://github.com/RazorAnt – mg1075

ответ

52

У меня есть работа с этим кодом.

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");  
} 
+0

Документ, PdfWriter и абзац непризнаны. Какое пространство имен должно быть добавлено? – michael

+0

Это тоже работало для меня, отлично! –

+0

Я обновил код, чтобы удалить ненужный memystream. –

3

Вы можете создать собственный класс, чтобы изменить тип содержимого и добавить файл в ответ.

http://haacked.com/archive/2008/05/10/writing-a-custom-file-download-action-result-for-asp.net-mvc.aspx

+6

Как указано в начале этого сообщения в блоге, FileResult выходит из коробки с помощью Asp.Net MVC, поэтому больше не требуется кодирование собственного. – NerdFury

108

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"); 
+0

См. Мое редактирование выше –

+0

@ Тони, вам нужно сначала закрыть документ и сбросить поток. – Geoff

+2

Джефф, я пытаюсь добиться этого, но имею подобные проблемы. Я получаю сообщение об ошибке во время выполнения «Не могу получить доступ к закрытому потоку». Но если я не закрываю его, ничего не возвращается. – littlechris

15

Если вы возвращаете FileResult из метода действия, и использовать метод File() расширения на контроллере, делая то, что вы хотите, довольно легко. В методе File() есть переопределения, которые будут принимать двоичное содержимое файла, путь к файлу или Stream.

public FileResult DownloadFile() 
{ 
    return File("path\\to\\pdf.pdf", "application/pdf"); 
} 
11

У меня возникли аналогичные проблемы, и я наткнулся на решение. Я использовал два сообщения, один из stack, который показывает способ возврата для загрузки, а другой one, который показывает рабочее решение для 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 
    // https://stackoverflow.com/questions/779430/asp-net-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"); 
} 
+0

Ответ Killer ... БОЛЬШОЕ СПАСИБО !!! – Prethen

+0

Отличный пример! Это именно то, что я искал! - Pete - –

+0

Использование? Закрыть? Dispose? Промывать? Кто заботится о утечке памяти? – vbullinger

2

Вы обычно делаете 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(); 
3

Я знаю, этот вопрос старый, но я думал, что я разделю это, как я не мог найти ничего подобного.

Я хотел создать свои мнения/модели как обычный используя Бритва и иметь их показан как PDFS.

Таким образом, я контролировал презентацию pdf с использованием стандартного вывода html, а не выяснял, как компоновать документ с помощью iTextSharp.

Проект и исходный код доступен здесь с инструкциями NuGet установки:

https://github.com/andyhutch77/MvcRazorToPdf

Install-Package MvcRazorToPdf 
16

Вы должны указать:

Response.AppendHeader("content-disposition", "inline; filename=file.pdf"); 
return new FileStreamResult(stream, "application/pdf") 

Для файла, чтобы быть открыт непосредственно в вместо скачано

+0

* «Контент-рассылка» * - Я предполагаю, что вы имеете в виду ** «Контент-распоряжение» ** ... – mkl

+0

@mkl Действительно, отредактировал мой ответ – Machinegon

+0

Спасибо! Я искал везде, как это сделать! – Scottie

1

если вы возвращаете 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 [email protected] 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 
     } 
Смежные вопросы