从Oracle过程运行Powershell命令

时间:2019-05-31 11:09:26

标签: android oracle powershell oracle12c

我需要从android studio应用程序将pdf文档打印到网络打印机。我想按所有图像和格式打印pdf,但是我发现的解决方案仅允许从pdf中提取和打印文本。

我还看到了解决方案,提到了诸如Ghostscript之类的工具,这些工具本应将pdf转换为postscript文件,但是这些工具不适用于Android Studio,或者至少我还没有弄清楚如何将其集成到我的工具中应用。我无法为jPDFPrint之类的工具付费,该工具完全可以满足我的需求。

我开始考虑解决方法,并想到了将pdf作为blob发送到oracle数据库并从过程中调用power shell命令以将其打印到特定打印机的想法。

我已经创建并测试了以下命令,可以从PC上运行到网络打印机,效果很好。

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

现在我需要有关oracle部分的帮助。是否可以从oracle 12c内调用或运行powershell命令并将pdf blob以及打印机名称传递给它?

2 个答案:

答案 0 :(得分:0)

您可以使用PL / SQL软件包DBMS_SCHEDULER过程create_program,使用program_type =>'EXECUTABLE'来执行所需的操作。然后,您需要将数据发送到oracle的进程创建一个作业来调用该程序。 DBMS_SCHEDULER软件包非常复杂,因此您可能需要四处寻找教程/技巧。您可能要搜索https://asktom.oracle.com来查找初学者。

答案 1 :(得分:0)

将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。它还必须能够调用上面建议的过程,以将保存的BLOB提取到数据库服务器文件中,因此在保存BLOB之后将调用此提取ODF并创建打印蝙蝠脚本的过程。

“任务计划程序”作业会轮询bat脚本的目录,运行它们会删除它们。

您不能从Oracle内部直接向服务器主机发出命令。您可以使用DBMS_SCHEDULER。在上面的示例中,作业将doc_id作为参数,并通过DBMS_SCHEDULER.RUN_JOB执行该操作。我不记得如何精确地执行此操作,但是我希望Windows中的Task Scheduler的其他建议对您有帮助。