Dynamics AX ile Server-Side PDF Yazdırma İşlemi

Bir projede dynamics ax’ın hem 2009 hemde 2012 sürümü ile ağda bulunan bir yazıcıdan, harici pdf dosyalarının düzenli olarak çıktısını almam gerekti. Buradaki en büyük sorun koddan pdf yazdırabilmek. Bu X++ dan değil pdf formatının kendisi sebebiyle sıkıntılı bir durum. Çoğu programlama dili ve yazıcı native olarak pdf formatını desteklemiyor. PDF’i yazdırabilmek için third party araçlar kullanmanız gerekiyor. Çeşitli araştırma ve denemelerden sonra sonuca ulaştım. Adım adım yapalım.

İşlemlere başlamadan önce yapmamız gereken ilk şey çıktı almak istediğiniz ağ yazıcısını AOS makinasına tanıtmak. AOS makinasına admin kullanıcısı ile bağlanıp, denetim masasındaki yazıcılar bölümünden kullanacağınız ağ yazıcınızı tanıtın. Ardından AX da çıktı almak için aşağıdaki kodu kullanabilirsiniz. Fakat sadece bu kadarla bitmiyor.

 

public static void printFile(str _filePath, int _copies = 1)
{
    PrinterName                         printerName;
    System.Diagnostics.ProcessStartInfo processInfo;
    System.Diagnostics.Process          process;
    System.Exception                    interopException;
    str                                 args;
    str                                 exePath;
    ;

    printerName = AYXAutoInvoicingParameters::find().InvoicePrinterPath;

    try
    {
        new InteropPermission(InteropKind::ClrInterop).assert();


        args = strfmt('-s "%1" -prn "%2" -copies %3 "-alerts_no"', _filePath, printerName, _copies);
        exePath = @"C:\Program Files (x86)\2Printer\2Printer.exe";

        process = new System.Diagnostics.Process();

        processInfo = process.get_StartInfo();
        processInfo.set_FileName(exePath);
        processInfo.set_Arguments(args);

        processInfo.set_CreateNoWindow(true);
        processInfo.set_WindowStyle(System.Diagnostics.ProcessWindowStyle::Hidden);

        process.Start();

        CodeAccessPermission::revertAssert();
    }
    catch (Exception::CLRError)
    {
        interopException = CLRInterop::getLastException();
        while (!CLRInterop::isNull(interopException.get_InnerException()))
        {
            interopException = interopException.get_InnerException();
        }

        error(_filePath);
        error(strFmt("Hata: %1", CLRInterop::getAnyTypeForObject(interopException.get_Message())));
        throw error("Dosya yazdırılamadı.");
    }
}

 

Öncelikle bu kodun server-side çalışması gerekiyor. Nasıl yapılacağını bilmeyenler buradaki makaleden faydalanabilir.

Yukarıdaki kodda yaptığımız işlem X++ üzerinden .NET’in “System.Diagnostics.Process” sınıfını kullanarak AOS makinasında belirli parametrelerle pdf’imizi yazdıracak bir exe çalıştırmak. Exe pdf dosyamızın yolunu, yazdırmak istediğimiz yazıcının yolunu ve kopya sayısı gibi istediğimiz bilgileri alıp yazdırmayı yapıyor. İşlemi bitirdiken sonra ise kendini otomatik kapatıyor. O sebeple “process.Start()” ifadesinden sonra exe’nin durumunu kontrol etmiyorum. Asenkron çalışıyor. Buda bize performans kazandırıyor.

Ben bu örnekde ise 2Printer isminde lisanslı bir araç kullandım. Kendisi pdf formatını destekleyen command line batch printing tool’udur. Yukarıdaki kodu kullanabilmek için bu uygulamayı AOS makinasına kurmalısınız. Free olarakda kullanılabiliyor fakat bazı kısıtlamaları var. Tabi tek çözüm bu değil. Tamamiyle ücretsiz alternatiflerde var. Gelin inceleyelim…

 

Batch PDF Printing

2Printer yerine Adobe Acrobat Reader, Foxit Reader gibi yazılımlarıda kullanabilirsiniz. Kullanım şeklimiz aynı. Tek yapmanız gereken bu araçları AOS makinasına kurmak. Sonrasında kodda exe path’ini ve alacağı parametre formatını güncellemek. Amaç bu uygulamarı headless olarak gui olmadan çalıştırmak ve yazdırma işlemini tamamladıktan sonra kapatmak. Fakat 2Printer dan farklı olarak:

 

Adobe Acrobat Reader: Command line üzerinden çalışmaya uygun değil. Komut ile çalıştırmak istediğinizde mutlaka GUI açıyor ve yazdırmadan sonra kendini otomatik kapatmıyor. Command printing için kendisinin ücretli API’si mevcut. Fakat burada anlatılana göre çok yavaş. Eski versiyonlarının command line üzerinden çalışmaya elverişli olduğunu okumuştum. Test edip uygun sürüm bulunabilir.

Foxit Reader: Command line üzerinden çalışmaya uygun. Parametre olarak pdf dosyasını ve yazıcı yolunu verip çıktı alabilirsiniz. Herhangi bir GUI açmıyor. Fakat process’i kendini otomatik kapatmayabiliyor. 1-2 sn bekleyip kendiniz koddan kill etmelisiniz. Ayrıca kopya sayısı, renkli/siyah-beyaz vs detaylı komutları desteklemiyor.

Örneğin 3 kopya almak isterseniz exe’yi 3 defa çağırıp her seferinde bitmesini bekliyorsunuz. 6-7 saniye süren bu süreç yukarıda bahsettiğim asenkron çalışan 2Printer ile 1 sn sürmüyor. Eğer performans sorununuz yoksa tavsiye ederim. Buradaki yazıyı inceleyerek entegre edebilirsiniz.

Native: Bazı yazıcıların kendiliğinden pdf desteği olabiliyor. Bu yazıcılar için tek yapmanız gereken yazıcının ağdaki yoluna pdf dosyasını kopyalamak. Bunu yaptığınızda, yazıcı varsayılan ayarları ile pdf’i yazdıracaktır. Örneğin bir müşterimin ofisindeki Konica Minolta marka insan ebatındaki yazıcı hiç bu toollara ihtiyaç kalmadan bu işi halletti.

Kendimiz yazalım: Bu ihtimalde aklınıza gelebilir. Fakat ilk araştırmalarımda c# için önüme çıkan bütün pdf kütüphaneleri ücretliydi. Kütüphaneye para vermek yerine direkt tool’u almak daha mantıklı.

Bu konuyu ciddi kafaya takmış durumdayım 🙂 c# için ücretsiz bir pdf kütüphanesi bulursam açık kaynak ve tamamen ücretsiz bir command line printing tool’u yazmayı düşünüyorum. Yazdığım takdirde bu yazıya link veriyor olurum. Eğer sizin bildiğiniz, kullandığınız araçlar varsa yorumlarda paylaşabilirsiniz.

 

Hoşçakalın.

 

Bir Cevap Yazın