8

内部 Web アプリケーションがドキュメントをプリンタに透過的に送信する必要があります。ユーザーが最寄りのプリンターを選択すると、Web アプリケーションはユーザーが選択したプリンターに印刷ジョブを送信します。

ロールアウトする必要がある最初のプリンターはキャノンです。私の質問は次のとおりです。印刷するドキュメントをネットワーク経由で特定のキャノンに送信するにはどうすればよいですか? 質問のCannonの種類はiR5570で、記載する書類は主にWordとPDFになります

私は現在、ひどい IE のみの Canon 開発者サイトに取り組んでいますが、誰かが私を正しい方向に向けるか、サードパーティのアセンブリに向けてくれることを願っています :)

4

7 に答える 7

6

今日の多くのプリンターや多機能デバイスは、PDFの直接印刷をサポートしています。これにより、問題の1つが解決する可能性があります。PDFをプリンタに送信するだけです。実際、URLの送信をサポートしているものもあり、プリンターはドキュメントを取得して印刷します。Lexmarkは確かにこれを行っており、他のいくつかのベンダーも同様に行っていると思います。これは、Word文書を処理する必要があることを意味します。Word 2007はPDF(Microsoftからインストールされたアドインを使用)をサポートしており、この関数をプログラムで使用して、C#で大成功を収めました。

そのためのコードは次のとおりです。

Microsoft.Office.Interop.Word.ApplicationClass msWord = new Microsoft.Office.Interop.Word.ApplicationClass();

object paramUnknown = Type.Missing;
object missing = Type.Missing;
object paramSaveChangesNo = Microsoft.Office.Interop.Word.WdSaveOptions.wdDoNotSaveChanges;
//object paramFonts = Microsoft.Office.Interop.Word.wde
object paramFormatPDF = Microsoft.Office.Interop.Word.WdSaveFormat.wdFormatPDF;
object paramTrue = true;
object paramReadOnly = true;  
object sourceDoc = @"c:\input.doc"                              
object target = @"c:\output.pdf";

msWord.Visible = false;

//open .doc
msWord.Documents.Open(ref sourceDoc, ref paramUnknown, ref paramReadOnly, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown);

//so it won't show on the taskbar
msWord.Application.Visible = false;
msWord.WindowState = Microsoft.Office.Interop.Word.WdWindowState.wdWindowStateMinimize;

//save .doc to new target name and format
msWord.ActiveDocument.SaveAs(ref targetDoc, ref paramFormatPDF, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramTrue, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown);

msWord.ActiveDocument.Close(ref missing, ref missing, ref missing);

msWord.Quit(ref paramSaveChangesNo, ref paramUnknown, ref paramUnknown);

最後に、デバイスがPDF印刷をサポートしていない場合は、Ghostscriptまたはその他のツールを使用してPDFをPSまたはPCLに変換できます。これは、管理されていないコードや最悪の場合を実行し、GSコマンドラインをシェルアウトして実行することを意味するため、最大ではありません。現在、これはWebアプリの1つで実行されており、正常に機能します。余談ですが、私たちは印刷用ではなく、多数のPDFを結合するためにそれを行いますが、最終的には同じように機能します。

于 2008-10-21T13:10:23.063 に答える
6

その質問のキー フレーズは「Web アプリケーション」です。

HTTP 経由で HTML+Javascript のみを使用する通常の Web アプリでは、ドキュメントを直接プリンターに送信することはできません。これが Web ブラウザーが存在する理由の 1 つであり、その機能がなければ、公共の FAX 機が行うのと同じ種類のジャンクをすべてのプリンターが収集することになります。

したがって、何らかの回避策が必要です。1 つのオプションは、フラッシュ、Silverlight、Java アプレット、さらにはグリースモンキーなどの一般的なプラグインに基づいて構築することです。もう 1 つは、ホストされた winforms コントロールやカスタム ブラウザー拡張機能などのカスタム プラグインです。

デプロイメント環境を完全に制御 (または知識) しているように見え、この環境がかなり均一であるという点で、あなたは非常に幸運です。これは、他の人が検討し始めた追加のオプションがあることを意味します。環境内のすべてのプリンターを Web サーバーにインストールできる場合は、組み込みの .Net プリンター クラス (System.Drawing.Printing名前空間内) を使用してそれらのプリンターを一覧表示するか、ユーザーに表示して選択できるようにするのはかなり簡単です。または、ある種の IP からプリンターへのマッピング テーブルを保持し、Web アプリからそのプリンターに直接印刷します。このスキームでは、他の方法よりも高いレベルの信頼でアプリを実行する必要がある場合があることに注意してください。

次に、実際に PDF と Word 文書を印刷します。acrobat については、次のリンクを確認してください:
http://support.adobe.com/devsup/devsup.nsf/docs/52080.htm (Wayback マシン)
少し古くなっていることに注意してください。ただし、この概念はまだ有効であると思います。期待どおりに動作することを確認するには、いくつか試してみる必要があります。

Word の場合、私は通常、Web アプリでの Office の相互運用/自動化のファンではありません。ただし、この場合、ドキュメントを編集しているのではなく、印刷するのに十分な時間ロードするだけです。また、別の希少なリソース (プリンター) に依存しているという事実は、Web サーバーが処理できる範囲を超えてスケ​​ーリングすることを防ぐ必要があります。そのため、Web プロジェクトでの Office オートメーションが理にかなっているというまれなケースがあるかもしれません。

于 2008-10-20T14:40:55.063 に答える
1

PrintDocumentドキュメントには、 C#からの印刷の詳細な例が含まれています。プリンター名は、ローカル プリンターまたはプリンター共有を指している必要があります。PDF ドキュメントの印刷については、print-to-a-pdf-printer-programaticallyを参照してください。

于 2008-10-20T14:21:19.520 に答える
1

Word や PDF 文書をプリンターが理解できるものに変換する必要があります。通常、これは前者の場合は Word 自体であり、後者の場合はある種の PDF ビューアーです。これらのプログラムは、出力を送信するプリンタを指定する必要があります。

考えられる方法の 1 つは、ドキュメントを Postscript ファイルとして保存することです。その後、C# アプリケーションから Postscript 対応のプリンターに直接送信できます。それがおそらく最も簡単な方法でしょう。

于 2008-10-20T14:23:04.087 に答える
1

SQL レポート サービスの機能を確認するのに 5 分かかる場合があります。私は過去にそれを使用して、PDFを直接印刷しました。

http://blogs.msdn.com/bryanke/articles/71491.aspx

于 2008-10-20T14:39:58.920 に答える
0

問題のドキュメント タイプが Windows に認識されている場合 (DOC や PDF のように)、Windows 動詞を使用してそれを行うことができますか?

Codeproject PDF の例 : PDF995 および FreePDF_XP フリーウェア プリンターを使用した自動 PDF 変換 MSDN : 動詞とファイルの関連付け

于 2008-10-20T14:16:52.430 に答える
-1

このコードは完全に機能します。AdobeReader自体を使用して印刷します

使用のヒント1-adobereaderへの独自のインストールパスを指定することを忘れないでください2-印刷するプリンターのプロパティからプリンター名を取得してください

次のようなクラスを使用します。

PdfFilePrinter p = new PdfFilePrinter();

p.PdfFileName = @"c:\1.pdf";
p.Print();
p.PdfFileName = @"c:\2.pdf";
p.Print();

クラスは:

public class PdfFilePrinter
{
    /// <summary>
    /// Initializes a new instance of the <see cref="PdfFilePrinter"/> class.
    /// </summary>
    public PdfFilePrinter()
    {
        adobeReaderPath = @"C:\Program Files\Adobe\Reader 9.0\Reader\AcroRd32.exe";
        printerName = "HP LaserJet P2055 Series PCL6";
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="PdfFilePrinter"/> class.
    /// </summary>
    /// <param name="pdfFileName">Name of the PDF file.</param>
    public PdfFilePrinter(string pdfFileName)
    {
        this.PdfFileName = pdfFileName;
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="PdfFilePrinter"/> class.
    /// </summary>
    /// <param name="pdfFileName">Name of the PDF file.</param>
    /// <param name="printerName">Name of the printer.</param>
    public PdfFilePrinter(string pdfFileName, string printerName)
    {
        this.pdfFileName = pdfFileName;
        this.printerName = printerName;
    }

    /// <summary>
    /// Gets or sets the name of the PDF file to print.
    /// </summary>
    public string PdfFileName
    {
        get { return this.pdfFileName; }
        set { this.pdfFileName = value; }
    }
    string pdfFileName;

    /// <summary>
    /// Gets or sets the name of the printer. A typical name looks like '\\myserver\HP LaserJet PCL5'.
    /// </summary>
    /// <value>The name of the printer.</value>
    public string PrinterName
    {
        get { return this.printerName; }
        set { this.printerName = value; }
    }
    string printerName;

    /// <summary>
    /// Gets or sets the working directory.
    /// </summary>
    public string WorkingDirectory
    {
        get { return this.workingDirectory; }
        set { this.workingDirectory = value; }
    }
    string workingDirectory;

    /// <summary>
    /// Prints the PDF file.
    /// </summary>
    public void Print()
    {
        Print(-1);
    }

    /// <summary>
    /// Prints the PDF file.
    /// </summary>
    /// <param name="milliseconds">The number of milliseconds to wait for completing the print job.</param>
    public void Print(int milliseconds)
    {
        if (this.printerName == null || this.printerName.Length == 0)
            this.printerName = PdfFilePrinter.defaultPrinterName;

        if (PdfFilePrinter.adobeReaderPath == null || PdfFilePrinter.adobeReaderPath.Length == 0)
            throw new InvalidOperationException("No full qualified path to AcroRd32.exe or Acrobat.exe is set.");

        if (this.printerName == null || this.printerName.Length == 0)
            throw new InvalidOperationException("No printer name set.");

        // Check whether file exists.
        string fqName = String.Empty;
        if (this.workingDirectory != null && this.workingDirectory.Length != 0)
            fqName = Path.Combine(this.workingDirectory, this.pdfFileName);
        else
            fqName = Path.Combine(Directory.GetCurrentDirectory(), this.pdfFileName);
        if (!File.Exists(fqName))
            throw new InvalidOperationException(String.Format("The file {0} does not exist.", fqName));

        // TODO: Check whether printer exists.

        try
        {
            DoSomeVeryDirtyHacksToMakeItWork();

            //acrord32.exe /t          <- seems to work best
            //acrord32.exe /h /p       <- some swear by this version
            ProcessStartInfo startInfo = new ProcessStartInfo();
            startInfo.FileName = PdfFilePrinter.adobeReaderPath;
            string args = String.Format("/t \"{0}\" \"{1}\"", this.pdfFileName, this.printerName);
            //Debug.WriteLine(args);
            startInfo.Arguments = args;
            startInfo.CreateNoWindow = true;
            startInfo.ErrorDialog = false;
            startInfo.UseShellExecute = false;
            if (this.workingDirectory != null && this.workingDirectory.Length != 0)
                startInfo.WorkingDirectory = this.workingDirectory;

            Process process = Process.Start(startInfo);
            if (!process.WaitForExit(milliseconds))
            {
                // Kill Adobe Reader/Acrobat
                process.Kill();
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

    /// <summary>
    /// For reasons only Adobe knows the Reader seams to open and shows the document instead of printing it
    /// when it was not already running.
    /// If you use PDFsharp and have any suggestions to circumvent this function, please let us know.
    /// </summary>
    void DoSomeVeryDirtyHacksToMakeItWork()
    {
        if (PdfFilePrinter.runningAcro != null)
        {
            if (!PdfFilePrinter.runningAcro.HasExited)
                return;
            PdfFilePrinter.runningAcro.Dispose();
            PdfFilePrinter.runningAcro = null;
        }
        // Is any Adobe Reader/Acrobat running?
        Process[] processes = Process.GetProcesses();
        int count = processes.Length;
        for (int idx = 0; idx < count; idx++)
        {
            try
            {
                Process process = processes[idx];
                ProcessModule module = process.MainModule;

                if (String.Compare(Path.GetFileName(module.FileName), Path.GetFileName(PdfFilePrinter.adobeReaderPath), true) == 0)
                {
                    // Yes: Fine, we can print.
                    PdfFilePrinter.runningAcro = process;
                    break;
                }
            }
            catch { }
        }
        if (PdfFilePrinter.runningAcro == null)
        {
            // No: Start an Adobe Reader/Acrobat.
            // If you are within ASP.NET, good luck...
            PdfFilePrinter.runningAcro = Process.Start(PdfFilePrinter.adobeReaderPath);
            PdfFilePrinter.runningAcro.WaitForInputIdle();
        }
    }
    static Process runningAcro;

    /// <summary>
    /// Gets or sets the Adobe Reader or Adobe Acrobat path.
    /// A typical name looks like 'C:\Program Files\Adobe\Adobe Reader 7.0\AcroRd32.exe'.
    /// </summary>
    static public string AdobeReaderPath
    {
        get { return PdfFilePrinter.adobeReaderPath; }
        set { PdfFilePrinter.adobeReaderPath = value; }
    }
    static string adobeReaderPath;

    /// <summary>
    /// Gets or sets the name of the default printer. A typical name looks like '\\myserver\HP LaserJet PCL5'.
    /// </summary>
    static public string DefaultPrinterName
    {
        get { return PdfFilePrinter.defaultPrinterName; }
        set { PdfFilePrinter.defaultPrinterName = value; }
    }
    static string defaultPrinterName;
}
于 2012-07-04T09:09:43.503 に答える