You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

打印文本文件生成空白PDF的技术问题求助

解决打印TXT到虚拟PDF打印机生成空文档的问题

我之前也踩过这个坑,用pdf995或者Adobe PDF当虚拟打印机时,经常因为细节没处理好生成空PDF。结合你的CodeActivity场景,给你几个排查和解决的方向:

1. 核心问题:PrintDocument没有实际输出内容

空PDF最常见的原因是PrintPage事件没有正确绘制文本。你的代码片段没写完执行逻辑,大概率是这里漏了关键步骤。你需要确保在Execute方法中,给PrintDocument绑定PrintPage事件,并在事件里读取TXT内容、绘制到打印画布上。

完整的示例代码参考:

using System;
using System.Activities;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;

namespace Advanced.PDF.Extended
{
    public class PrintTxtFile : CodeActivity
    {
        [Category("Input")]
        [Description(@"For Ex : C:\Users\userid\Desktop\Input\exam.txt")]
        public InArgument<string> FilePath { get; set; }

        [Category("Input")]
        [Description(@"Output PDF path (for silent print)")]
        public InArgument<string> OutputPdfPath { get; set; }

        protected override void Execute(CodeActivityContext context)
        {
            string filePath = context.GetValue(FilePath);
            string outputPath = context.GetValue(OutputPdfPath);

            if (!File.Exists(filePath))
            {
                throw new FileNotFoundException("Target TXT file not found", filePath);
            }

            PrintDocument pd = new PrintDocument();
            
            // 绑定打印页面事件——输出内容的核心逻辑
            string[] textLines = File.ReadAllLines(filePath);
            int currentLineIndex = 0;
            pd.PrintPage += (sender, e) =>
            {
                float yPosition = e.MarginBounds.Top;
                float leftMargin = e.MarginBounds.Left;
                Font printFont = new Font("Arial", 10);
                float lineHeight = printFont.GetHeight(e.Graphics);

                // 逐行绘制文本,自动处理多页
                while (currentLineIndex < textLines.Length)
                {
                    // 检查是否超出当前页面底部
                    if (yPosition + lineHeight > e.MarginBounds.Bottom)
                    {
                        e.HasMorePages = true;
                        return;
                    }

                    e.Graphics.DrawString(
                        textLines[currentLineIndex],
                        printFont,
                        Brushes.Black,
                        leftMargin,
                        yPosition
                    );

                    yPosition += lineHeight;
                    currentLineIndex++;
                }

                e.HasMorePages = false;
            };

            // 配置虚拟打印机
            pd.PrinterSettings.PrinterName = "Adobe PDF"; // 换成pdf995的名称即可适配
            // 针对Adobe PDF,直接指定输出路径避免弹出保存对话框
            pd.PrinterSettings.PrintToFile = true;
            pd.PrinterSettings.PrintFileName = outputPath;

            try
            {
                pd.Print();
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException("Print failed", ex);
            }
        }
    }
}

2. 虚拟打印机的静默打印配置

虚拟打印机默认会弹出保存对话框,如果你的程序是后台运行(比如Workflow里的CodeActivity),对话框会被阻塞,导致打印流程中断,最终生成空文件:

  • 针对pdf995:可以通过修改注册表开启静默模式,并指定默认保存路径:
    using Microsoft.Win32;
    
    // 打印前配置pdf995静默参数
    RegistryKey pdf995Key = Registry.CurrentUser.OpenSubKey(@"Software\pdf995\Settings", true);
    if (pdf995Key != null)
    {
        pdf995Key.SetValue("Silent", 1); // 1代表开启静默模式
        pdf995Key.SetValue("SavePath", Path.GetDirectoryName(outputPath));
        pdf995Key.Close();
    }
    
  • 针对Adobe PDF:代码里已经通过PrintToFile属性指定了输出路径,就能避免弹出对话框。

3. 权限与路径问题

  • 确保程序有读取输入TXT文件写入输出PDF路径的权限,尤其是在服务、IIS或者Workflow宿主环境下,运行账户的权限很容易被忽略。
  • 输出路径一定要用绝对路径,避免相对路径导致的文件找不到问题。

4. 页面边距与内容范围检查

有时候看似空PDF,其实是文本超出了打印页面的可见范围。可以调整DefaultPageSettings的边距,确保内容能被绘制在页面内:

pd.DefaultPageSettings.Margins = new Margins(20, 20, 20, 20); // 上下左右各留20像素边距

建议先从第一个点开始排查,确保PrintPage事件里确实有绘制文本的逻辑,这是最容易出错的地方。如果还是有问题,可以加日志打印文件内容、打印机名称、输出路径等信息,方便定位问题。

内容的提问来源于stack exchange,提问作者Rajan

火山引擎 最新活动