nak*_*tic 6 python printing pdf reportlab jdf
我以编程方式在Python和Reportlab Toolkit中创建PDF文件,每个文件包含数千个文档,每个文档具有可变数量的页面.
我的问题是我需要指示打印机应打印每页的介质类型(例如,文档第一页的预打印信头).看来我需要生成一种持有这种信息的工作单.
我在创建JDF作业单方面取得了一些成功,但这些仅在我组织运行Xerox Freeflow Server 8版的最新打印机上运行.
理想情况下,我需要一个解决方案,它也适用于我们的Freeflow服务器版本7和Xerox DocuSP打印机.我尝试将JDF票证发送到这些打印机失败了.
我可以使用其他类型的票务系统,还是让我们所有的打印机识别JDF文件?
我遇到了同样的问题.最后,我发现由于对PDF格式的误解导致我的方式错误.我们认为PDF文件是打印机的WYSIWYG.不是这种情况.在任何类型的打印流程中,PDF文件通常都会转换为某种中间格式,PostScript,TIFF图像或PCL.
这可能发生在您的本地计算机上,这就是您需要驱动程序或打印机本身的原因.如果它在打印机上发生,您只需将PDF文件传输到另一台计算机并设置适当的转换系统.
这一切都很好,但是PDF没有定义页面顺序,这对于打印就绪格式非常违反直觉.这意味着您的文档没有第一页,您将无法以任何形式或形式本地定义它.
你有两个解决方案:
选择打印机架构并使用其设置媒体类型的独特方法,这是一种痛苦,不可移植.
转换为允许设置媒体类型的格式,并包括页面排序的概念,例如PostScript.然后添加媒体命令并将此文件一起发送到您的打印机.如果您的打印机具有用于读取所选中间格式的驱动程序,则应将命令转换为其媒体切换版本.这更便携但仍然不完美.
这类似于将C程序转换为程序集以将其移植到新架构的想法.它主要起作用,但你必须把每个系统都搞砸了.
假设的管道将是:
创建PDF文件>通过PDF-to-PostScript转换实用程序或库运行>运行自定义词法分析器以在每个新页面添加媒体类型命令>将PostScript文件发送到打印机
这是一项很多工作,但这是你要找到的唯一可以解决问题的方法.
%{
char paper[] = 'yourPaper';
%}
%option 8bit outfile="scanner.c"
%option nounput nomain noyywrap
%option warn
%%
showpage { printf("showpage\nsetpagedevice MediaType '%s'", paper); }
%%
int main(int argc, char **argv);
int main (argc,argv)
int argc;
char **argv;
{
yylex();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
以上是一个非常简单的词法分析器,用于查找从stdin获取的每个showpage命令并输出showpage setpagedevice命令集.setpagedevice MediaType命令是与打印机无关的设置用于页面的纸张类型的方法.
flex -Cf scanner.l
gcc -O -o lineCount.exe scanner.c
Run Code Online (Sandbox Code Playgroud)
它通过stdin接受输入并输出到stdout.
下面列出了更完整的词法分析器.它使用GNU getopts作为命令行选项,并且有两个规则,因此它也将为第一页设置页面设备.它可能无法完美地抓取页面,并且它只有一个用于纸张类型的变量,因此功能有限.另一方面,它非常开放,但是您希望它确定要使用的页面设备.
要么识别它正在查看的页面类型的新规则,要么是每页有一行的附加输入文件,这两个立即浮现在脑海中.
/*
* This file is part of flex.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE.
*/
/**************************************************
Start of definitions section
***************************************************/
%{
/* A template scanner file to build "scanner.c". */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
/*#include "parser.h" */
//put your variables here
char FileName[256];
FILE *outfile;
char inputName[256];
char paper[] = 'yourPaper';
// flags for command line options
static int specificFile_flag = 0;
static int output_flag = 0;
static int help_flag = 0;
%}
%option 8bit outfile="scanner.c"
%option nounput nomain noyywrap
%option warn
%%
/************************************************
start of rules section
*************************************************/
/* These flex patterns will eat all input */
EndSetup { printf("showpage\nsetpagedevice MediaType '%s'", paper); }
showpage { printf("showpage\nsetpagedevice MediaType '%s'", paper); }
%%
/****************************************************
Start of code section
*****************************************************/
int main(int argc, char **argv);
int main (argc,argv)
int argc;
char **argv;
{
/****************************************************
The main method drives the program. It gets the filename from the
command line, and opens the initial files to write to. Then it calls the lexer.
After the lexer returns, the main method finishes out the report file,
closes all of the open files, and prints out to the command line to let the
user know it is finished.
****************************************************/
int c;
// The GNU getopt library is used to parse the command line for flags
// afterwards, the final option is assumed to be the input file
while (1) {
static struct option long_options[] = {
/* These options set a flag. */
{"help", no_argument, &help_flag, 1},
/* These options don't set a flag. We distinguish them by their indices. */
{"useStdOut", no_argument, 0, 'o'},
{0, 0, 0, 0}
};
/* getopt_long stores the option index here. */
int option_index = 0;
c = getopt_long (argc, argv, "o",
long_options, &option_index);
/* Detect the end of the options. */
if (c == -1)
break;
switch (c) {
case 0:
/* If this option set a flag, do nothing else now. */
if (long_options[option_index].flag != 0)
break;
printf ("option %s", long_options[option_index].name);
if (optarg)
printf (" with arg %s", optarg);
printf ("\n");
break;
case 'o':
output_flag = 1;
break;
case '?':
/* getopt_long already printed an error message. */
break;
default:
abort ();
}
}
if (help_flag == 1) {
printf("proper syntax is: traySwitch.exe [OPTIONS]... INFILE OUTFILE\n");
printf("adds tray switching information to postscript file\n\n");
printf("Option list: \n");
printf("-o sets output to stdout\n");
printf("--help print help to screen\n");
printf("\n");
printf("inputfile example: traySwitch.exe test.ps\n");
printf("If infile is left out, then stdin is used for input.\n");
printf("If outfile is a filename, then that file is used.\n");
printf("If there is no outfile, then infile-EDIT.ps is used.\n");
printf("There cannot be an outfile without an infile.\n");
return 0;
}
//Get the filename off the command line and redirect it to input
//if there is no filename or it is a - then use stdin.
if (optind < argc) {
FILE *file;
file = fopen(argv[optind], "rb");
if (!file) {
fprintf(stderr, "Flex could not open %s\n",argv[optind]);
exit(1);
}
yyin = file;
strcpy(inputName, argv[optind]);
}
else {
printf("no input file set, using stdin. Press ctrl-c to quit");
yyin = stdin;
strcpy(inputName, "\b\b\b\b\bagainst stdin");
}
//Increment current place in argument list
optind++;
/********************************************
If no input name, then output set to stdout.
If no output name then copy input name and add -EDIT.csv.
If input name is '-' then output set to stdout,
otherwise use output name.
*********************************************/
if (optind > argc) {
yyout = stdout;
}
else if (output_flag == 1) {
yyout = stdout;
}
else if (optind < argc){
outfile = fopen(argv[optind], "wb");
if (!outfile) {
fprintf(stderr, "Flex could not open %s\n",FileName);
exit(1);
}
yyout = outfile;
}
else {
strncpy(FileName, argv[optind-1], strlen(argv[optind-1])-4);
FileName[strlen(argv[optind-1])-4] = '\0';
strcat(FileName, "-EDIT.ps");
outfile = fopen(FileName, "wb");
if (!outfile) {
fprintf(stderr, "Flex could not open %s\n",FileName);
exit(1);
}
yyout = outfile;
}
yylex();
if (output_flag == 0) {
fclose(yyout);
}
printf("Flex program finished running file %s\n", inputName);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我在Xerox 支持论坛上收到了来自“ RogerK-Xerox ”的回复。
Xerox 使用基于 XML 的票务系统,称为 Xerox 打印指令格式 (XPIF)。您可以通过打开 Xerox 自定义打印驱动程序、对一些打印属性进行编程,然后导出 Xerox 作业单来了解此格式的工作原理。这是通过选择打印驱动程序上的“高级”选项卡,选择 Xerox 作业单旁边的“+”并选择“导出 Xerox 作业单...”,然后按“导出...”按钮来完成的。
为了完全访问 XPIF 编程指南,我相信您必须在http://www.xerox-solutions.net/Partners上注册
我尝试了上述方法,它确实生成了一个带有作业单指令的 XML 文件,该文件可能会重新加载到打印驱动程序中。现在我正在寻找一种将这些文件与打印机热文件夹一起使用的方法,这更符合我们当前的工作流程。打印机需要以某种方式知道哪个 XPIF 票据属于哪个 PDF 文件。
似乎可以通过简单地连接两个文件来将 XPIF 文件添加到 PDF 文件的开头。然后可以将该文件拖到热文件夹中,并且 Xerox 打印机知道如何将作业单与 PDF 分开。
我已经测试了这个方法,它按预期工作:-)。将一些任意 XML 数据附加到 PDF 文件的开头会导致该文件无法在 Adobe Acrobat 中打开。但令人惊讶的是,此类文件在 Evince 文档查看器中打开得很好。
| 归档时间: |
|
| 查看次数: |
3806 次 |
| 最近记录: |