Я пытаюсь написать код, который проставляет в паспорте имя пользователя системы, дату и изображение его подписи (которое я храню в виде varbinary в базе данных sql и байта в модели).Вот мой код:
private async void button_ApprovePassport_Click(object sender, EventArgs e)
{
await ProcessPassportPdfAsync();
}
private async Task ProcessPassportPdfAsync()
{
try
{
// Check if a document is selected
if (gridView_PortalDocs.IsSelected())
{
var PortalDoc = gridView_PortalDocs.GetSelectedDataRow
();
if (PortalDoc != null)
{
EmployeePortalService EPS = new EmployeePortalService();
if (PortalDoc.PortalFileID == null)
{
cGlobal.ShowErrorMessage("PortalFileID is null. Cannot retrieve document.");
return;
}
var Data = await EPS.GetDocument(PortalDoc.PortalFileID);
if (Data != null && !string.IsNullOrEmpty(Data.FileData))
{
// Convert base64 string to byte array
byte[] fileBytes = Convert.FromBase64String(Data.FileData);
// Create a memory stream from the byte array
using (MemoryStream inputStream = new MemoryStream(fileBytes))
{
// Process the PDF (stamp it)
using (MemoryStream processedStream = StampPdf(inputStream))
{
// Save the processed PDF to a temporary file
string tempFilePath = Path.Combine(Path.GetTempPath(), $"StampedPassport_{Guid.NewGuid()}.pdf");
File.WriteAllBytes(tempFilePath, processedStream.ToArray());
// Open the PDF with the default viewer
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(tempFilePath) { UseShellExecute = true });
// Convert the processed stream back to a base64 string
string processedBase64 = Convert.ToBase64String(processedStream.ToArray());
// Using the API for the document reupload here
// Update the PortalFiles table here
MessageBox.Show("Passport PDF processed and approved successfully.", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
else
{
cGlobal.ShowErrorMessage("The document data could not be retrieved from the server or is empty.");
}
}
else
{
cGlobal.ShowErrorMessage("The selected document information is invalid.");
}
}
else
{
cGlobal.ShowInfoMessage("Please select a document to process.");
}
}
catch (Exception ex)
{
cGlobal.ShowErrorMessage($"An error occurred while processing the passport PDF: {ex.Message}");
}
}
private MemoryStream StampPdf(MemoryStream inputStream)
{
// Get the user's signature and first name from the controller
// Use Stefi's for testing then switch to cGlobal.SystemUserID
var SystemUserSignature = Controller.GetSystemUserSignature(345);
// Check if the signature was retrieved successfully
if (SystemUserSignature == null || SystemUserSignature.Count == 0)
{
throw new Exception("User signature not found. Please add one in Access Control.");
}
// Retrieve the first user's details (assuming there's at least one entry)
var user = SystemUserSignature[0];
// Ensure we're using UTF-8 encoding (important for PdfSharp)
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
// Load the existing document
PdfDocument document = PdfReader.Open(inputStream, PdfDocumentOpenMode.Modify);
// Get the first page (you might want to stamp all pages)
PdfPage page = document.Pages[0];
// Create graphics object for drawing
XGraphics gfx = XGraphics.FromPdfPage(page);
// Create fonts using system fonts
XFont font = new XFont("Arial", 12);
XFont largeFont = new XFont("Arial", 24);
// Create a semi-transparent brush for the background of the stamp
XColor stampColor = XColor.FromArgb(128, 255, 0, 0); // Semi-transparent red
XBrush stampBrush = new XSolidBrush(stampColor);
// Draw a rectangle for the stamp background
gfx.DrawRectangle(stampBrush, 50, 50, 250, 100);
// Add text for the stamp
gfx.DrawString("APPROVED", largeFont, XBrushes.White, new XRect(50, 50, 250, 50), XStringFormats.Center);
// Add approval details
gfx.DrawString($"By: {user.Forename}", font, XBrushes.White, new XRect(60, 100, 230, 25), XStringFormats.TopLeft);
gfx.DrawString($"Date: {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}", font, XBrushes.White, new XRect(60, 125, 230, 25), XStringFormats.TopLeft);
// If the signature is available, draw it on the PDF
if (user.Signature != null && user.Signature.Length > 0)
{
// Load the signature image from the byte array
using (var signatureImage = new MemoryStream(user.Signature))
{
XImage image = XImage.FromStream(signatureImage);
gfx.DrawImage(image, 50, 150, 150, 50); // Position and size of the signature
}
}
// Save the document to a new MemoryStream
MemoryStream outputStream = new MemoryStream();
document.Save(outputStream, false);
outputStream.Position = 0; // Reset stream position to the beginning
return outputStream;
}
Я получаю сообщение об ошибке: «Произошла ошибка при обработке PDF-файла паспорта: внутренний буфер MemoryStream недоступен». Поэтому я не думаю, что вы можете использовать два MemoryStream одновременно. Каковы мои альтернативы для достижения этой цели?
Все, что я пробовал, это делать это через MemorySteam.
Я пытаюсь написать код, который проставляет в паспорте имя пользователя системы, дату и изображение его подписи (которое я храню в виде varbinary в базе данных sql и байта в модели).Вот мой код: [code]private async void button_ApprovePassport_Click(object sender, EventArgs e) { await ProcessPassportPdfAsync(); }
private async Task ProcessPassportPdfAsync() { try { // Check if a document is selected if (gridView_PortalDocs.IsSelected()) { var PortalDoc = gridView_PortalDocs.GetSelectedDataRow (); if (PortalDoc != null) { EmployeePortalService EPS = new EmployeePortalService(); if (PortalDoc.PortalFileID == null) { cGlobal.ShowErrorMessage("PortalFileID is null. Cannot retrieve document."); return; }
var Data = await EPS.GetDocument(PortalDoc.PortalFileID); if (Data != null && !string.IsNullOrEmpty(Data.FileData)) { // Convert base64 string to byte array byte[] fileBytes = Convert.FromBase64String(Data.FileData);
// Create a memory stream from the byte array using (MemoryStream inputStream = new MemoryStream(fileBytes)) { // Process the PDF (stamp it) using (MemoryStream processedStream = StampPdf(inputStream)) { // Save the processed PDF to a temporary file string tempFilePath = Path.Combine(Path.GetTempPath(), $"StampedPassport_{Guid.NewGuid()}.pdf"); File.WriteAllBytes(tempFilePath, processedStream.ToArray());
// Open the PDF with the default viewer System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(tempFilePath) { UseShellExecute = true });
// Convert the processed stream back to a base64 string string processedBase64 = Convert.ToBase64String(processedStream.ToArray());
// Using the API for the document reupload here
// Update the PortalFiles table here
MessageBox.Show("Passport PDF processed and approved successfully.", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information); } } } else { cGlobal.ShowErrorMessage("The document data could not be retrieved from the server or is empty."); } } else { cGlobal.ShowErrorMessage("The selected document information is invalid."); } } else { cGlobal.ShowInfoMessage("Please select a document to process."); } } catch (Exception ex) { cGlobal.ShowErrorMessage($"An error occurred while processing the passport PDF: {ex.Message}"); } }
private MemoryStream StampPdf(MemoryStream inputStream) { // Get the user's signature and first name from the controller // Use Stefi's for testing then switch to cGlobal.SystemUserID var SystemUserSignature = Controller.GetSystemUserSignature(345);
// Check if the signature was retrieved successfully if (SystemUserSignature == null || SystemUserSignature.Count == 0) { throw new Exception("User signature not found. Please add one in Access Control."); }
// Retrieve the first user's details (assuming there's at least one entry) var user = SystemUserSignature[0];
// Ensure we're using UTF-8 encoding (important for PdfSharp) Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
// Load the existing document PdfDocument document = PdfReader.Open(inputStream, PdfDocumentOpenMode.Modify);
// Get the first page (you might want to stamp all pages) PdfPage page = document.Pages[0];
// Create graphics object for drawing XGraphics gfx = XGraphics.FromPdfPage(page);
// Create fonts using system fonts XFont font = new XFont("Arial", 12); XFont largeFont = new XFont("Arial", 24);
// Create a semi-transparent brush for the background of the stamp XColor stampColor = XColor.FromArgb(128, 255, 0, 0); // Semi-transparent red XBrush stampBrush = new XSolidBrush(stampColor);
// Draw a rectangle for the stamp background gfx.DrawRectangle(stampBrush, 50, 50, 250, 100);
// Add text for the stamp gfx.DrawString("APPROVED", largeFont, XBrushes.White, new XRect(50, 50, 250, 50), XStringFormats.Center);
// If the signature is available, draw it on the PDF if (user.Signature != null && user.Signature.Length > 0) { // Load the signature image from the byte array using (var signatureImage = new MemoryStream(user.Signature)) { XImage image = XImage.FromStream(signatureImage); gfx.DrawImage(image, 50, 150, 150, 50); // Position and size of the signature } }
// Save the document to a new MemoryStream MemoryStream outputStream = new MemoryStream(); document.Save(outputStream, false);
outputStream.Position = 0; // Reset stream position to the beginning return outputStream; } [/code] Я получаю сообщение об ошибке: «Произошла ошибка при обработке PDF-файла паспорта: внутренний буфер MemoryStream недоступен». Поэтому я не думаю, что вы можете использовать два MemoryStream одновременно. Каковы мои альтернативы для достижения этой цели? Все, что я пробовал, это делать это через MemorySteam.
Я пытаюсь написать код, который проставляет в паспорте имя пользователя системы, дату и изображение его подписи (которое я храню в виде varbinary в базе данных sql и байта в модели).Вот мой код:
private async void...
Я пытаюсь написать код, который проставляет в паспорте имя пользователя системы, дату и изображение его подписи (которое я храню в виде varbinary в базе данных sql и байта в модели).Вот мой код:
private async void...
У меня есть класс MemoryStream2, который наследуется от MemoryStream, с той лишь разницей, что он вводит новую переменную — идентификатор ссылки. Теперь у меня ситуация, когда определенная функция возвращает MemoryStream, и мне нужно...
У меня есть класс MemoryStream2, который наследуется от MemoryStream, с той лишь разницей, что он вводит новую переменную — идентификатор ссылки. Теперь у меня ситуация, когда определенная функция возвращает MemoryStream, и мне нужно...
У меня есть класс MemoryStream2, который наследуется от MemoryStream, с той лишь разницей, что он вводит новую переменную — идентификатор ссылки. Теперь у меня ситуация, когда определенная функция возвращает MemoryStream, и мне нужно...