Запустите команду Powershell из процедуры Oracle - PullRequest
2 голосов
/ 31 мая 2019

Мне нужно распечатать PDF-документы на моем сетевом принтере из приложения Android Studio.Я хочу распечатать PDF как есть со всеми изображениями и форматированием, однако, решения, которые я нашел, позволяют только извлекать и печатать текст из PDF.

Я также видел решения, в которых упоминаются такие инструменты, как Ghostscript и т. Д., Которые должны конвертировать pdf в файл postscript, но эти инструменты не работают с Android Studio или, по крайней мере, я не понял, как интегрироватьих в мое приложение.Я не могу заплатить за такие инструменты, как jPDFPrint, который делает именно то, что мне нужно.

Я начал думать об обходном пути и натолкнулся на мысль отправить мой pdf-файл в виде большого двоичного объекта в мою базу данных Oracle и вызвать команду Power Shell изпроцедура для печати на определенный принтер.

Я создал и проверил приведенную ниже команду для печати на моем сетевом принтере с моего ПК, которая прекрасно работает.

    Start-Process -FilePath “c:\test.pdf” –Verb PrintTo '\\PrintServer\PrinterName' -PassThru | %{sleep 10;$_} | kill

Теперь мне нужна помощь с оракулом.Можно ли вызвать или запустить команду powershell изнутри oracle 12c и передать ему файл PDF, а также имя принтера?

Ответы [ 2 ]

0 голосов
/ 31 мая 2019

Чтобы извлечь BLOB в PDF.

Создайте свою системную папку, например, c:\printthis.

Затем создайте объект каталога Oracle, сопоставленный с этой папкой:

CREATE OR REPLACE DIRECTORY print_dir AS 'C:\print_this';

GRANT READ WRITE ON DIRECTORY print_dir TO PUBLIC;

Эта процедура позволяет извлечь BLOB-файл в файл.

CREATE OR REPLACE PROCEDURE extract_pdf ( p_id IN VARCHAR2 ) AS
   CURSOR c1 IS 
      SELECT doc_blob, doc_name
      FROM doc_table
      WHERE doc_id = p_id;
   r1         c1%ROWTYPE;
   v_size     NUMBER( 5,0) := 32000;
   v_len      NUMBER(38,0);
   v_buffer   RAW(32000);
   v_file     UTL_FILE.FILE_TYPE;
BEGIN
   OPEN c1;
   FETCH c1 INTO r1;
   v_file  := UTL_FILE.FOPEN('PRINT_DIR', r1.doc_name, 'wb', 32760 );
   v_start := 1;
   v_len   := DBMS_LOB.GETLENGTH( r.bbl_fic );
   WHILE v_start <= v_len LOOP
      DBMS_LOB.READ(
             r.bbl_fic,
             LEAST( v_len - v_start + 1, v_size ),
             v_start,
             v_buffer
           );
      UTL_FILE.PUT_RAW( v_file, v_buffer );
      UTL_FILE.FFLUSH( v_file ); 
      v_start := v_start + v_size;
    END LOOP;
    UTL_FILE.FCLOSE( v_file );
--  Write the CMD file
    v_file := UTL_FILE.FOPEN('PRINT_DIR', r1.doc_name || '.bat', 'w' );
    UTL_FILE.PUT_LINE(     'Start-Process -FilePath “c:\print_this\' || r1.doc_name || '” –Verb PrintTo '\\PrintServer\PrinterName' -PassThru | %{sleep 10;$_} | kill' );
    UTL_FILE.CLOSE(v_file);
END;
/

Выполняемое задание Windows At опрашивает папку c:\print_this на наличие файлов и запускает команду .bat, а затем удаляет ее.

@ECHO OFF
setlocal enabledelayedexpansion
for %%f in (c:\print_this\*.bat) do (
  echo "Name: %%f"
  powershell %%f
  del %%f
)

Остается вопрос, как сшить это вместе.Ваше приложение для Android вызывает вашу процедуру для сохранения PDF как BLOB.Также необходимо иметь возможность вызывать процедуру, предложенную выше, для извлечения сохраненного большого двоичного объекта в файл сервера базы данных, поэтому эта процедура для извлечения ODF и создания сценария печати bat вызывается после сохранения большого двоичного объекта.

ЗадачаЗадание планировщика опрашивает каталог для сценариев bat, запускает их, удаляет их.

Невозможно напрямую выполнить команду для хоста сервера из Oracle.Вы можете использовать DBMS_SCHEDULER.В приведенном выше примере задание будет принимать doc_id в качестве параметра и выполнять его через DBMS_SCHEDULER.RUN_JOB.Я не могу вспомнить, как это сделать точно, но я надеюсь, что мое другое предложение с планировщиком задач в Windows будет для вас плодотворным.

0 голосов
/ 31 мая 2019

Вы можете использовать пакет PL / SQL DBMS_SCHEDULER Процедура create_program, используя program_type => 'EXECUTABLE', чтобы делать то, что вы хотите.Тогда у вас будет процесс, который отправляет данные в oracle, создающий задание для вызова этой программы.Пакет DBMS_SCHEDULER довольно сложный, поэтому вам, вероятно, придется поискать учебные пособия / советы;Вы можете искать https://asktom.oracle.com для начинающих.

...