2017-08-02 5 views
1

私はiTextSharpを使用して、剃刀のビューをC#コントローラ経由でダウンロードできるpdfに変換しています。この現在の実装では完璧に動作、しかし私は、PDFコントローラへのビューからモデルを渡し、ここでは、ブラウザ内iTextSharp .Netアクション結果ajaxでpdfとしてダウンロードする

をアクション結果のダウンロードがしたい私の現在のコントローラである:ここでは

public ActionResult Report(MyModel model) 
    { 
     // The below method is a custom implementation using iTextSharp 
     return new FoilPdfActionResult(model, (writer, document) => 
     { 
      document.SetPageSize(PageSize.LETTER.Rotate()); 
      document.NewPage(); 
     }) 
     { 
      FileDownloadName = "testing.pdf", 
     }; 
    } 

は私ですAJAXの電話:

function sendForm(model) { 
     $.ajax({ 
      type: 'POST', 
      url: '@Url.Action("Report")', 
        data: model, 
        success: function (data) { 
         console.log(data); 

        }, 
        error: function (xhr, textStatus, errorThrown) { 

        } 
       }); 
    } 

"/ Report"で直接コントローラのパスにアクセスすると、ブラウザ内でファイルが正しくダウンロードされます。 上記のajax呼び出しを使用してコントローラを呼び出すと、モデルが正しく渡され、成功した場合はpdf結果がdata変数を返しますが、pdfは実際にはダウンロードされません。データ変数に渡す代わりにpdfをダウンロードすることは可能ですか?

+1

AJAX経由で直接ダウンロードすることはできません。 – SLaks

+1

なぜあなたはAJAXコールでこれを行う必要があると思いますか?ユーザーをURLに誘導するだけです。ファイルがダウンロードされると、表示されたページは変更されません。 – DavidG

+0

AJAXなしでやりたいことを達成する別の実装がありますか?これまでのところ、AJAXはC#コントローラにカスタムオブジェクトを渡す唯一の方法でした – slugibihl

答えて

1

最近(2)同様の状況があり、ajax経由でそれを行うには実際の焼き焼き方法がないことがわかりました。良いニュース:それは実際には本当に簡単で、あなたはajaxコールが必要ありません。

あなたができることは、フォームの投稿要求を送信することです。コントローラーのポストアクションでファイルをメモリに生成し、ビューの再読み込みを行わずにファイルを返すために "return File()"を使用します。ここ

はiTextSharpを使用した例である。

例モデル:

public class TestM 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public int Number { get; set; } 
} 

ビュー(基本自動作成生成)

@model DeleteMeWeb45.Models.TestM 

@{ 
    ViewBag.Title = "Index"; 
} 

<h2>Index</h2> 


@using (Html.BeginForm()) 
{ 
    @Html.AntiForgeryToken() 

    <div class="form-horizontal"> 
     <h4>TestM</h4> 
     <hr /> 
     @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 
     <div class="form-group"> 
      @Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.LastName, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(model => model.Number, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.EditorFor(model => model.Number, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.Number, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

     <div class="form-group"> 
      <div class="col-md-offset-2 col-md-10"> 
       <input type="submit" value="Create" class="btn btn-default" /> 
      </div> 
     </div> 
    </div> 
} 

コントローラー:で

public ActionResult Index() 
    { 
     TestM t = new TestM(); 
     return View(t); 
    } 
    [HttpPost] 
    public ActionResult Index(TestM t) 
    { 
     if(ModelState.IsValid) 
     { 
      Document doc = new Document(iTextSharp.text.PageSize.LETTER, 10, 10, 42, 30); 
      byte[] pdfBytes; 
      BaseFont bfTimes = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1252, false); 
      Font timesBold = new Font(bfTimes, 12, Font.BOLD); 

      using (var mem = new MemoryStream()) 
      { 
       PdfWriter wri = PdfWriter.GetInstance(doc, mem); 
       doc.SetMargins(20, 20, 20, 60); 
       doc.Open(); 
       var orderInfoTable = new PdfPTable(2); 
       orderInfoTable.AddCell(new Phrase("First Name:", timesBold)); 
       orderInfoTable.AddCell(new Phrase(t.FirstName, timesBold)); 
       orderInfoTable.AddCell(new Phrase("Last Name:", timesBold)); 
       orderInfoTable.AddCell(new Phrase(t.LastName, timesBold)); 
       orderInfoTable.AddCell(new Phrase("Number:", timesBold)); 
       orderInfoTable.AddCell(new Phrase(t.Number.ToString(), timesBold)); 

       doc.Add(orderInfoTable); 
       doc.Close(); 
       pdfBytes = mem.ToArray(); 
      } 

      return File(pdfBytes, "application/pdf", "Weeeeeee_" + DateTime.Now.ToString("_MM-dd-yyyy-mm-ss-tt") + ".pdf"); 
     } 
     else 
     { 
      return View(t); 
     } 


    } 

ev

ビュー:

変更1あなたがあるとして、ボタンを提出する(それが保存または何でもありません)と、ちょうどあなたのような上記の例を修正するだろうダウンロード余分なボタンが欲しいあなたのフォームを維持したいENT 。

@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { id = "transferForm" })) 

変更2.別の場所でフォームを送信するボタンやJSを追加します:

<div class="row"> 
    <div class="btn btn-primaryDark btn-sm" id="btnRunReport" style="min-width:120px;">Run Report</div> 
</div> 



@section Scripts { 
    @Scripts.Render("~/bundles/jqueryval") 

    <script> 
     $(document).ready(function() { 
      $("#btnRunReport").click(function() { 
       $('#transferForm').attr('action', "/Home/JSFUN").submit(); 
      }); 

     }); 
    </script> 

} 

コントローラーの変更:をフォームにIDを与えます1. POSTリクエストを処理するための新しいコントローラのアクションを作成します。

[HttpPost] 
    public ActionResult JSFUN(TestM t) 
    { 
     Document doc = new Document(iTextSharp.text.PageSize.LETTER, 10, 10, 42, 30); 
     byte[] pdfBytes; 
     BaseFont bfTimes = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1252, false); 
     Font timesBold = new Font(bfTimes, 12, Font.BOLD); 

     using (var mem = new MemoryStream()) 
     { 
      PdfWriter wri = PdfWriter.GetInstance(doc, mem); 
      doc.SetMargins(20, 20, 20, 60); 
      doc.Open(); 
      var orderInfoTable = new PdfPTable(2); 
      orderInfoTable.AddCell(new Phrase("First Name:", timesBold)); 
      orderInfoTable.AddCell(new Phrase(t.FirstName, timesBold)); 
      orderInfoTable.AddCell(new Phrase("Last Name:", timesBold)); 
      orderInfoTable.AddCell(new Phrase(t.LastName, timesBold)); 
      orderInfoTable.AddCell(new Phrase("Number:", timesBold)); 
      orderInfoTable.AddCell(new Phrase(t.Number.ToString(), timesBold)); 

      doc.Add(orderInfoTable); 
      doc.Close(); 
      pdfBytes = mem.ToArray(); 
     } 

     return File(pdfBytes, "application/pdf", "Weeeeeee_" + DateTime.Now.ToString("_MM-dd-yyyy-mm-ss-tt") + ".pdf"); 

    } 

ユーザーがフォームを使用することができます。この方法では、ボタンと異なる目的のためにエクスポートボタンを提出します。

関連する問題