簡體   English   中英

使用 C# 從 API 下載 PDF 文件

[英]Download PDF File from API Using C#

我正在創建一個控制台應用程序

  1. 連接到供應商 API 以提取兩個日期和日期之間提交的費用的憑證編號
  2. 下載隨費用提交的收據的 PDF 副本

第一部分,我工作正常。 我能夠使用以下代碼連接到供應商 API 並解析返回的 XML 以創建一組憑證編號(需要獲取 PDF 圖像):

static async Task RunAsyncCR()
        {
            using (var client = new HttpClient())
            {
                var values = new Dictionary<string, string>
                {
                    {"un","SomeUser"},
                    {"pw","SomePassword"},
                    {"method","getVoucherInvoices"},
                    {"fromDate","05/30/2016"},
                    {"toDate", "06/13/2016"}
                };

                var content = new FormUrlEncodedContent(values);

                Console.WriteLine("Connecting...");

                var response = await client.PostAsync("https://www.chromeriver.com/receipts/doit", content);

                Console.WriteLine("Connected...");

                var responseString = await response.Content.ReadAsStringAsync();

                char[] DelimiterChars = {'<'};

                String[] xmlReturn = responseString.Split(DelimiterChars);

                string[] VoucherNumber = new string[500];

                int i = 0;

                foreach (string s in xmlReturn)
                {
                    if (s.Contains("voucherInvoice>") && s != "/voucherInvoice>\n    ")
                    {
                        VoucherNumber[i] = s.Substring(15, 16);

                        i++;
                    }
                }

                Array.Resize(ref VoucherNumber, i);

是的,可能有更好的方法來做到這一點,但它可以工作並返回我期望的值。

現在,我遇到的問題是,當我連接回 API 以檢索文件時,我似乎無法將文件下載到指定的文件路徑。

我可以使用連接回 API

            i = 0;

            foreach (string x in VoucherNumber)
            {
                Console.WriteLine("Get receipt: " + x);

                var NewValues = new Dictionary<string, string>
                {
                    {"un","SomeUser"},
                    {"pw","SomePassword"},
                    {"method","getReceiptsWithCoverPage"},
                    {"voucherInvoiceForPdf", VoucherNumber[i]}
                };

                var NewContent = new FormUrlEncodedContent(NewValues);

                var NewResponse = await client.PostAsync("https://www.chromeriver.com/receipts/doit", NewContent);

                string NewResponseString = await NewResponse.Content.ReadAsStringAsync();

但我似乎無法將響應寫入有效文件 (PDF)

這是我逐步執行代碼時我的 Autos 窗口的屏幕截圖,我需要在其中下載文件:

汽車

我的問題是,從現在開始,我該如何將文件保存到我的系統中?

我試圖采用我從做Console.WriteLine(NewResponseString);得到的編碼響應Console.WriteLine(NewResponseString); 並使用System.IO.File.WriteAllLines()方法使用指定的文件路徑/名稱將其寫入文件,但這會導致空白文件。 我也花了一些時間研究 Google/Stackoverflow 的深度,但不明白如何實現我發現的結果。

任何和所有的幫助將不勝感激。

所以我認為您需要有關 Streams 的幫助。 返回的HttpContent實際上是一個System.Net.Http.StreamContent實例,它表明您正在獲取內容。 它只是從該實例獲取流(內容)並將其保存到文件的問題。

var NewResponse = await client.PostAsync("https://www.chromeriver.com/receipts/doit", NewContent);

System.Net.Http.HttpContent content = NewResponse.Content; // actually a System.Net.Http.StreamContent instance but you do not need to cast as the actual type does not matter in this case

using(var file = System.IO.File.Create("somePathHere.pdf")){ // create a new file to write to
    var contentStream = await content.ReadAsStreamAsync(); // get the actual content stream
    await contentStream.CopyToAsync(file); // copy that stream to the file stream
}

我恭敬地建議您閱讀一些有關 Streams 工作原理的書。 這是許多語言中的常見結構,您可能在不久的將來必須再次處理。

首先,你確定有一個文件開始嗎? 我可以建議使用開源庫 PdfSharp。 我個人自己使用它,效果很好。 至於下載文件,也許這可以幫助你......

同步下載

using System.Net;
WebClient webClient = new WebClient();
webClient.DownloadFile("http://example.com/myfile.txt", @"c:\\myfile.txt");

http://www.csharp-examples.net/download-files/

首先從 NewResponse 創建 StreamReader

Stream receiveStream = NewResponse.GetResponseStream ();
StreamReader readStream = new StreamReader (receiveStream, Encoding.UTF8);

然后定義一個 StremaWriter 以寫入文件。

using (var writer = new StreamWriter(@"C:\MyNewFile.pdf", append: false))
{
    writer.Write(readStream.ReadToEnd());
}

替代方法是

var httpContent = NewResponse.Content; 

using(var newFile = System.IO.File.Create(@"C:\MyNewFile.pdf"))
{ 
    var stream = await httpContent.ReadAsStreamAsync();
    await stream.CopyToAsync(newFile);
}

這是我所做的,沒有找到任何其他滿足我情況的解決方案:

using (var client = new System.Net.Http.HttpClient())

{
  client.DefaultRequestHeaders.Add("Authorization", "someapikey");
  client.BaseAddress = new Uri("https://someurl.com");
  byte[] bytes = client.GetByteArrayAsync(client.BaseAddress).ConfigureAwait(false).GetAwaiter().GetResult();

  
  string pdfFilePath = @"c:\somepath"
  System.IO.File.WriteAllBytes(pdfFilePath, bytes);

  //Note that below is only to open PDF in standard viewer, not necessary
  var process = new System.Diagnostics.Process();
  var startInfo = new System.Diagnostics.ProcessStartInfo()
{
    FileName=pdfFilePath,
    WorkingDirectory = System.IO.Path.GetDirectoryName(pdfFilePath),
    UseShellExecute = true
}

  process.StartInfo = startInfo;
  process.Start();

}

使用此代碼從 API 下載 pdf。 它將字符串數據轉換為字節並為您提供必要的解決方案。

HttpWebRequest request = (HttpWebRequest) WebRequest.Create(URL);

request.ContentType = "application/pdf;charset=UTF-8";
request.Method = "GET";

using(HttpWebResponse response = (HttpWebResponse) request.GetResponse()) {

    BinaryReader bin = new BinaryReader(response.GetResponseStream());

    byte[] buffer = bin.ReadBytes((Int32) response.ContentLength);

    Response.Buffer = true;
    Response.Charset = "";

    Response.AppendHeader("Content-Disposition", "attachment; filename=+ filename); 

    Response.Cache.SetCacheability(HttpCacheability.NoCache);

    Response.ContentType = "application/pdf";

    Response.BinaryWrite(buffer);

    Response.Flush();

    Response.End();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM