2013-08-04 1 views
1

타사 html to pdf 변환 (DocRaptor)을 사용하고 있습니다. 자신의 사이트에 HTML을 게시하면 PDF로 응답합니다. 그들이 제공하는 시작 코드는 잘 작동하지만 파일을 하드 드라이브에 저장합니다. 브라우저를 통해 파일을 다운로드하도록 코드를 수정했습니다. 그래서 저는 HTTP 응답에서 얻은 데이터가 좋은 데이터라는 것을 100 % 확신합니다. 사용할 수있는 파일로 다시 어셈블 할 수 없습니다.HTTP 스트림에서 pdf를 어셈블하는 방법은 무엇입니까?

저는 어떻게 responseStream 데이터를 전달하는지 문제가 있다고 확신합니다. Try/Catch에 들어가면 모두 잘못 될 것 같습니다. C 프로그래밍과 웹 프로그래밍에 익숙하지 않으므로 여기 SO 사용자의 지침을 매우 감사하게 생각합니다. 감사. 여기 내 코드가있다.

  string postData = String.Format(PostFormat, 
      (string.IsNullOrEmpty(DocumentContent) ? "document_url" : "document_content"), 
      HttpUtility.UrlEncode(string.IsNullOrEmpty(DocumentContent) ? DocumentURL : DocumentContent), 
      HttpUtility.UrlEncode(Name), 
      HttpUtility.UrlEncode(type), 
      HttpUtility.UrlEncode(Test.ToString().ToLower()), 
      HttpUtility.UrlEncode(Strict), 
      HttpUtility.UrlEncode(PrinceOptions)); 

     var byteArray = Encoding.UTF8.GetBytes(postData); 

     HttpWebRequest request = (HttpWebRequest)WebRequest.Create(DocRaptorUrl); 
     request.Method = "POST"; 
     request.ContentType = "application/x-www-form-urlencoded"; 
     request.ContentLength = byteArray.Length; 
     using (var dataStream = request.GetRequestStream()) { dataStream.Write(byteArray, 0, byteArray.Length); } 

     System.IO.Stream stream = null; 

     try 
     { 
      using (HttpWebResponse httpResponse = (HttpWebResponse)request.GetResponse()) 
      { 
       using (System.IO.Stream responseStream = httpResponse.GetResponseStream()) 
       { 

        var filepath = @"C:\Users\David\Downloads\UberwriterUSRReport.pdf"; 
        HttpContext.Current.Response.ContentType = "application/pdf"; 

        // let the browser know how to open the PDF document, attachment or inline, and the file name 
        HttpContext.Current.Response.AddHeader("Content-Disposition", String.Format("attachment; filename=UberwriterUSRReport.pdf")); 

        stream = new System.IO.FileStream(filepath, System.IO.FileMode.Create); 

        CopyStream(responseStream, stream); 

        long bytestToRead = stream.Length; 

        while (bytestToRead > 0) 
        { 
         if (HttpContext.Current.Response.IsClientConnected) 
         { 
          byte[] buffer = new Byte[10000]; 
          int length = stream.Read(buffer, 0, 10000); 
          HttpContext.Current.Response.OutputStream.Write(buffer, 0, length); 
          HttpContext.Current.Response.Flush(); 

          bytestToRead = bytestToRead - length; 
         } 
         else 
         { 
          bytestToRead = -1; 
         } 
        } 
       } 
      } 
     } 

답변

3

파일을 브라우저에 보내기 전에 하드 드라이브에 저장하겠습니까? 왜냐하면 그것이 당신이 지금하고있는 일이기 때문입니다. 여기

stream = new System.IO.FileStream(filepath, System.IO.FileMode.Create); 

이 파일에 저장하고 :

CopyStream(responseStream, stream); 

보다도 난 당신이 어디 스트림을 닫습니다 표시되지 않습니다 원인하는 사용하여 문에 쓰기 동작을 둘러싸이다

다음으로, 파일을 저장 한 outputstream을 읽고 Response.Outputstream에 기록하려고합니다. 그리고 여러분은 이미 copystream을 구현 했으므로 여기서는 수동으로해야할까요?

using (HttpWebResponse httpResponse = (HttpWebResponse)request.GetResponse()) 
{ 
    using (System.IO.Stream responseStream = httpResponse.GetResponseStream()) 
    { 
     // let the browser know how to open the PDF document, attachment or inline, and the file name 
     HttpContext.Current.Response.AddHeader("Content-Disposition", String.Format("attachment; filename=UberwriterUSRReport.pdf")); 

     CopyStream(responseStream, HttpContext.Current.Response.OutputStream); 
    } 
} 
+0

아이디어를 제공해 주셔서 감사합니다. 나는 왜 그런지 정확히 모르겠다. 나는 당신의 제안에서 그것이 작동하도록하기 위해 한 가지를 편집해야했습니다. FileMode.Read 대신 FileMode.Open을 사용했습니다. "읽기"는 솔루션을 코딩 할 때 나에게 제공되는 옵션이 아닙니다. – stamm528

+0

보기 좋았습니다. 나는 그것이 마음에 든다는 것을 인정해야한다. 그래서 나는 오류가 있다는 것에 놀라지 않는다. :) – Stephen

+0

그것은 내게 국부적으로 일했지만, 나는 그것을 Azure와 질식에 게시했다. 나는 파일 경로가 문제라고 생각하고있다. responseStream을 가져 와서 마치 다운로드 한 파일 인 것처럼 브라우저에 바로 갈 수 있습니까? 그것은 내가 정말로 원하는 것입니다. 사용자가 버튼을 클릭하면 PDF가 생성되고 클라이언트 측에서 다운로드로 표시됩니다. – stamm528

1
: 당신은 모든 서버에 파일을 저장하지 않으려면,

using (HttpWebResponse httpResponse = (HttpWebResponse)request.GetResponse()) 
{ 
    using (System.IO.Stream responseStream = httpResponse.GetResponseStream()) 
    { 
     var filepath = @"C:\Users\David\Downloads\UberwriterUSRReport.pdf"; 
     HttpContext.Current.Response.ContentType = "application/pdf"; 

     // let the browser know how to open the PDF document, attachment or inline, and the file name 
     HttpContext.Current.Response.AddHeader("Content-Disposition", String.Format("attachment; filename=UberwriterUSRReport.pdf")); 

     using (var stream = new System.IO.FileStream(filepath, System.IO.FileMode.Create)) { 
      CopyStream(responseStream, stream); 
     } 

     using (var readstream = new System.IO.FileStream(filepath, System.IO.FileMode.Read)) { 
      CopyStream(readstream, HttpContext.Current.Response.OutputStream); 
     } 
    } 
} 

또는 :

HttpContext.Current.Response.OutputStream.Write(buffer, 0, length); 

그래서, 나는 그것이 같은 것을해야한다 말할 것

MUCHO는 나를 올바른 길로 인도 해준 스티븐에게 많은 감사를드립니다. 나는 그 구현을 더욱 세련시켰다. 필요한 코드가 더 많았습니다. 사용자가 버튼을 누르고 DocRaptor.com 사이트에 HTML을 게시 한 다음 생성 된 PDF로 응답하게하고 브라우저에 다운로드로 표시 할 파일을 사용자가 원한다. 다음은 Azure에서 테스트 한 최종 구현 코드입니다.

  try 
     { 
      using (HttpWebResponse httpResponse = (HttpWebResponse)request.GetResponse()) 
      { 
       using (System.IO.Stream responseStream = httpResponse.GetResponseStream()) 
       { 

        //var filepath = @"C:\Users\David\Downloads\UberwriterUSRReport.pdf"; 
        HttpContext.Current.Response.Clear(); 
        HttpContext.Current.Response.ContentType = "application/pdf"; 
        HttpContext.Current.Response.AddHeader("Content-Disposition", String.Format("atachment; filename=UberwriterUSRReport.pdf")); 
        HttpContext.Current.Response.BufferOutput = true; 

        CopyStream(responseStream, HttpContext.Current.Response.OutputStream); 

       } 
      } 
     } 
관련 문제