使用 SQL 数据库和 .NET 正确存储和检索 PDF 文件

问题描述 投票:0回答:1

我创建了一个 Web 应用程序,它将 PDF 文件发送到 SQL 数据库表,以便稍后加载并通过电子邮件发送。目前我的代码可以工作,并且 PDF 文件正在通过电子邮件发送,但是一旦打开 PDF,所有内容都会按预期显示,除了 PDF 中不再存在的背景图像。现在我不明白的是,如果我在将“IFormFile”发送到数据库之前使用“IFormFile”,则通过电子邮件发送的 PDF 文件会正确显示并包含其背景图像。让我觉得我一定是错误地将 PDF 文件转换为二进制格式或从二进制格式转换为 PDF 文件?

请查看我当前的代码:

Javascript ajax 到控制器: ajax

if(email) {
   var file = doc.output('blob');
   var fd = new FormData();
   fd.append('pdfFile',file);
   fd.append('jobNo',$('#jobNoInput').val());
   $.ajax({
       url: "/Jobs/SendInvoiceEmailToQueue",
       data: fd,
       dataType: 'text',
       processData: false,
       contentType: false,
       type: 'POST',
       success: function(data) {
           var data2 = JSON.parse(data);
           if(data2 == "SUCCESS")
           {
               quickToast('Invoice added to Email Queue for Job 
No: ' + $('#jobNoInput').val(), 'success', 'Added to Email Queue');
           }
       }
   });
} else {
   doc.save('Invoice.pdf');
}

上传PDF到数据库: upload pdf to database

public IActionResult SendInvoiceEmailToQueue(string jobNo)
{
var stream = Request.BodyReader.AsStream();
IFormFile pdfFile = Request.Form.Files[0];

string fileName = pdfFile.FileName;

var result = new StringBuilder();
using (var reader = new StreamReader(pdfFile.OpenReadStream()))
{
    result.Append(reader.ReadToEnd());
}

string base64 = result.ToString();
Byte[] bitmapData = new Byte[base64.Length];

var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(base64);

connectionString();
con.Open();
com.Connection = con;

var query = "INSERT INTO dbo.email_queue([JOBNO],[PDF],[EMAILADDRESS],[DATE],[TIME]) VALUES(@jobNo, @pdf, 'address', GETDATE(), CURRENT_TIMESTAMP)";
SqlParameter picparameter = new SqlParameter();
picparameter.SqlDbType = SqlDbType.Image;
picparameter.ParameterName = "pdf";
picparameter.Value = plainTextBytes;
SqlParameter jobNoparameter = new SqlParameter();
jobNoparameter.SqlDbType = SqlDbType.Int;
jobNoparameter.ParameterName = "jobNo";
jobNoparameter.Value = Int32.Parse(jobNo);
SqlCommand cmd = new SqlCommand(query, con);
cmd.Parameters.Add(picparameter);
cmd.Parameters.Add(jobNoparameter);
cmd.ExecuteNonQuery();
cmd.Dispose();
con.Close();
con.Dispose();

return new JsonResult("SUCCESS");
}

通过电子邮件检索并发送 PDF: enter image description here

public IActionResult SendInvoiceEmail(string queueNo)
{
    connectionString();
    con.Open();
    com.Connection = con;
    com.CommandText = "SELECT * FROM dbo.recovery_email_queue WHERE EmailQueueRecNo = '" + queueNo + "'";
    dr = com.ExecuteReader();

    while (dr.Read())
    {
        var imageSource = System.Text.Encoding.UTF8.GetString(((byte[])dr["PDF"]));
        var pdffile = (byte[])dr["PDF"];
        
        var pdfBytes = Encoding.UTF8.GetBytes(imageSource);
        var stream = new MemoryStream(pdfBytes);

        IFormFile file = new FormFile(stream, 0, pdfBytes.Length, "invoice", "invoice.pdf");

        //attach pdf
        var attachment = new Attachment(file.OpenReadStream(), "invoice.pdf");

        using (MailMessage mail = new MailMessage())
        {
            mail.From = new MailAddress("fromAdd");
            mail.To.Add("add");
            mail.Subject = "Test Sending Invoice";
            mail.Body = "<h1>This is body</h1>";
            mail.IsBodyHtml = true;

            mail.Attachments.Add(attachment);
            using (SmtpClient smtp = new SmtpClient("smtp-mail.outlook.com", 587))
            {
                smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
                smtp.UseDefaultCredentials = false;
                smtp.Credentials = new System.Net.NetworkCredential(ConfigurationManager.AppSettings["emailUser"].ToString(), ConfigurationManager.AppSettings["emailPass"].ToString());
                smtp.EnableSsl = true;
                smtp.Send(mail);
            }
        }
    }

    return new JsonResult("SUCCESS");
}

数据库列“PDF”的类型为

varbinary(MAX)
使用jsPDF生成的PDF文件

javascript c# jspdf varbinary
1个回答
0
投票

好吧,我已经找到了解决方案,问题在于我对 PDF 文件转换为二进制格式的理解。我们不能在这里使用流阅读器,因为这是文本!,一旦我更改代码以直接从返回的流中读取字节,一切都会按预期工作,并且图像包含在数据库加载的文件中。

服务器端方法的代码更改:

public async Task<IActionResult> SendInvoiceEmailToQueue(string jobNo)
    {
        IFormFile pdfFile = Request.Form.Files[0];

        var stream = pdfFile.OpenReadStream();
        var length = (int)stream.Length;
        byte[] data = new byte[length];
        await stream.ReadAsync(buffer: data, offset: 0, count: length);....

从数据库读取:

while (dr.Read())
        {
            var pdffile = (byte[])dr["PDF"];
            
            var stream = new MemoryStream(pdffile);

            IFormFile file = new FormFile(stream, 0, pdffile.Length, "invoice", "invoice.pdf");

            //Attach pdf
            var attachment = new Attachment(file.OpenReadStream(), "invoice.pdf");....
© www.soinside.com 2019 - 2024. All rights reserved.