You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET C#实现图片/PDF/Word多格式文件打印预览技术问询

Hey there! The problem you're facing is totally expected right now—your current code only works with image files because it directly loads and draws them to the print graphics context. PDFs and Word documents have complex internal structures, so we need to add format-specific logic to render them correctly for print preview. Let's walk through how to implement this step by step.

1. Problem Breakdown

Your printDocument1_PrintPage method assumes every file is an image, so when it tries to load a PDF/Word file with Image.FromFile(), it throws an exception (which you're catching, hence no preview shows up). We need to:

  • Detect the file type by extension
  • Use appropriate libraries to render each format to the print graphics
  • Handle multi-page documents (since PDFs and Word files often have multiple pages)
2. Required Libraries

First, install these NuGet packages to handle the different formats:

  • For PDFs: PdfiumViewer (a lightweight, reliable library to render PDF pages to Graphics)
  • For Word documents: FreeSpire.Doc (a free library that doesn't depend on Microsoft Office being installed)
3. Updated Code Implementation

Let's modify your existing code to add support for PDFs and Word files:

First, add the necessary using directives:

using PdfiumViewer;
using Spire.Doc;
using Spire.Doc.Documents;
using System.Drawing.Printing;
using System.IO;

Update your form-level variables to track multi-page documents:

private List<string> elements = new List<string>();
private int currentFileIndex = 0;
private int currentPageInFile = 0;
private PdfDocument pdfDoc = null;
private Document wordDoc = null;

Modify the button1_Click method (clean up state before loading new files):

private void button1_Click(object sender, EventArgs e)
{
    try
    {
        elements.Clear();
        var Files = new DirectoryInfo(@"E:\Desktop\").GetFilesByExtensions(".png", ".pdf", ".doc", ".docx");
        foreach (FileInfo file in Files)
        {
            elements.Add(file.FullName);
        }
        // Reset state for new print job
        currentFileIndex = 0;
        currentPageInFile = 0;
        pdfDoc?.Dispose();
        wordDoc?.Dispose();
        pdfDoc = null;
        wordDoc = null;
        
        printPreviewDialog1.Document = printDocument1;
        printPreviewDialog1.ShowDialog();
    }
    catch (Exception ex)
    {
        MessageBox.Show($"Error loading files: {ex.Message}");
    }
}

Update printDocument1_BeginPrint to reset state:

private void printDocument1_BeginPrint(object sender, PrintEventArgs e)
{
    currentFileIndex = 0;
    currentPageInFile = 0;
    
    // Clean up any leftover documents
    pdfDoc?.Dispose();
    wordDoc?.Dispose();
    pdfDoc = null;
    wordDoc = null;
}

The key update: printDocument1_PrintPage with format-specific rendering:

private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
    try
    {
        if (currentFileIndex >= elements.Count)
        {
            e.HasMorePages = false;
            return;
        }

        string filePath = elements[currentFileIndex];
        string extension = Path.GetExtension(filePath).ToLower();

        switch (extension)
        {
            case ".png":
                // Handle images with aspect ratio scaling
                using (Image img = Image.FromFile(filePath))
                {
                    float scale = Math.Min(e.MarginBounds.Width / (float)img.Width, e.MarginBounds.Height / (float)img.Height);
                    int scaledWidth = (int)(img.Width * scale);
                    int scaledHeight = (int)(img.Height * scale);
                    int x = e.MarginBounds.Left + (e.MarginBounds.Width - scaledWidth) / 2;
                    int y = e.MarginBounds.Top + (e.MarginBounds.Height - scaledHeight) / 2;
                    e.Graphics.DrawImage(img, x, y, scaledWidth, scaledHeight);
                }
                currentFileIndex++;
                currentPageInFile = 0;
                break;

            case ".pdf":
                // Load PDF if not already loaded
                if (pdfDoc == null)
                {
                    pdfDoc = PdfDocument.Load(filePath);
                }

                // Render current PDF page
                if (currentPageInFile < pdfDoc.PageCount)
                {
                    using (var pageBitmap = pdfDoc.RenderPage(currentPageInFile, e.MarginBounds.Width, e.MarginBounds.Height, PdfRenderFlags.Annotations))
                    {
                        e.Graphics.DrawImage(pageBitmap, e.MarginBounds.Location);
                    }
                    currentPageInFile++;
                    // Check for more pages in this PDF
                    e.HasMorePages = currentPageInFile < pdfDoc.PageCount;
                    // Move to next file if PDF is done
                    if (!e.HasMorePages)
                    {
                        currentFileIndex++;
                        currentPageInFile = 0;
                        pdfDoc.Dispose();
                        pdfDoc = null;
                        e.HasMorePages = currentFileIndex < elements.Count;
                    }
                }
                break;

            case ".doc":
            case ".docx":
                // Load Word document if not already loaded
                if (wordDoc == null)
                {
                    wordDoc = new Document();
                    wordDoc.LoadFromFile(filePath);
                }

                // Render current Word page
                if (currentPageInFile < wordDoc.PageCount)
                {
                    using (Bitmap pageBitmap = wordDoc.SaveToImages(currentPageInFile, ImageType.Bitmap))
                    {
                        float scale = Math.Min(e.MarginBounds.Width / (float)pageBitmap.Width, e.MarginBounds.Height / (float)pageBitmap.Height);
                        int scaledWidth = (int)(pageBitmap.Width * scale);
                        int scaledHeight = (int)(pageBitmap.Height * scale);
                        int x = e.MarginBounds.Left + (e.MarginBounds.Width - scaledWidth) / 2;
                        int y = e.MarginBounds.Top + (e.MarginBounds.Height - scaledHeight) / 2;
                        e.Graphics.DrawImage(pageBitmap, x, y, scaledWidth, scaledHeight);
                    }
                    currentPageInFile++;
                    // Check for more pages in Word doc
                    e.HasMorePages = currentPageInFile < wordDoc.PageCount;
                    // Move to next file if Word doc is done
                    if (!e.HasMorePages)
                    {
                        currentFileIndex++;
                        currentPageInFile = 0;
                        wordDoc.Dispose();
                        wordDoc = null;
                        e.HasMorePages = currentFileIndex < elements.Count;
                    }
                }
                break;

            default:
                // Handle unsupported formats
                e.Graphics.DrawString($"Unsupported file type: {extension}", new Font("Arial", 12), Brushes.Red, e.MarginBounds.Left, e.MarginBounds.Top);
                currentFileIndex++;
                currentPageInFile = 0;
                break;
        }

        // Final check for remaining files
        if (!e.HasMorePages)
        {
            e.HasMorePages = currentFileIndex < elements.Count;
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show($"Error printing page: {ex.Message}");
        // Move to next file to avoid getting stuck
        currentFileIndex++;
        currentPageInFile = 0;
        e.HasMorePages = currentFileIndex < elements.Count;
    }
}
4. Important Notes
  • Resource Management: We use using statements and explicit disposal to avoid memory leaks from open documents.
  • Scaling: All content is scaled to fit within the print margin bounds while maintaining aspect ratio, which improves preview readability.
  • Office Alternative: If you prefer using Microsoft.Office.Interop.Word instead of FreeSpire.Doc, you'll need to adjust the Word handling logic to use the Interop library's printing methods, but note this requires Office to be installed on the end user's machine.
5. Cleanup

Add a FormClosing handler to dispose of any open documents when the form closes:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    pdfDoc?.Dispose();
    wordDoc?.Dispose();
}

内容的提问来源于stack exchange,提问作者Let's Enkindle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:23:06