Comments 48
торт
Очень полезная штука. Спасибо. Даже и не думал, что настроить настолько легко
Права можно раздавать по ip клиентов который по теории должен быть в $ENV.
Эта технология может пригодиться для экономии трафика, когда печать идет через vpn/интернет. Сделать этот веб-принтер локально, а на стороне принтера сделать скрипт который будет брать эти pdf-ки и печатать.
У нас в компании сейчас на принтер летят raw-данные через vpn, в pdf виде экономия в районе 10..100 раз.
Эта технология может пригодиться для экономии трафика, когда печать идет через vpn/интернет. Сделать этот веб-принтер локально, а на стороне принтера сделать скрипт который будет брать эти pdf-ки и печатать.
У нас в компании сейчас на принтер летят raw-данные через vpn, в pdf виде экономия в районе 10..100 раз.
Раздавать права по IP — хорошая идея. В скрипт не включил только из-за того, что IP-адреса у многих провайдеров динамические. А в локальной сети ограничения, наверное, не нужны…
Ну вот и применение нашлось :-). А Вы правда посчитали экономию? Дело в том, что PDF-документы, генерируемые скриптом, содержат не текст, написанный шрифтами, а, фактически, картинки. Поэтому они больше, чем обычные PDF-ки.
Ну вот и применение нашлось :-). А Вы правда посчитали экономию? Дело в том, что PDF-документы, генерируемые скриптом, содержат не текст, написанный шрифтами, а, фактически, картинки. Поэтому они больше, чем обычные PDF-ки.
получилось, очень рад, зачем это, не знаю :)
спасибо
спасибо
web-pdf имеет достаточно узкое применение.
Вы просто замечательный обфускатор. Надеюсь для обычной работы вы используете более разумные имена у переменных, а то я не завидую вашим коллегам.
По поводу имен переменных — Вы правы, конечно.
Но, на мой взгляд, написать вместо $d что-нибудь типа $input_data — это превратить легкий компактный скрипт в более громоздкий.
Поэтому удобочитаемыми сделал только имена функций. А классы не стал делать за ненадобностью :-)
Но, на мой взгляд, написать вместо $d что-нибудь типа $input_data — это превратить легкий компактный скрипт в более громоздкий.
Поэтому удобочитаемыми сделал только имена функций. А классы не стал делать за ненадобностью :-)
зачет
в своё время писал веб-приложение на asp.net, там была поставлена задача конвертирования html-страницы в формат pdf. выкрутился я используя сторонний софт, консольную софтину wkhtmltopdf, найденную на code.google.com.
так что с уверенностью могу утверждать — задача весьма актуальная. поэтому я весьма благодарен вам за решение, приведённое в топике, весьма вероятно что оно пригодится и не раз.
так что с уверенностью могу утверждать — задача весьма актуальная. поэтому я весьма благодарен вам за решение, приведённое в топике, весьма вероятно что оно пригодится и не раз.
А по моему, очень даже не бесполезная вещь. Вот к примеру, есть газета, где часть авторов работают удалённо. Так вот, наверняка этим авторам, печатающим статьи в ворде, будет проще посылать статьи в редакцию, просто отправляя их на печать похожего скрипта, нежели возится с электронной почтой, атачтментами, загрузкой по фтп итд итп…
Интересно! Появилась пара вопросов.
>Нам понадобится (кроме головы и рук) только работающий web-сервер с поддержкой cgi-bin, к которому у нас есть доступ по FTP
FTP — это опечатка ( м.б. HTTP? ), или же я чего-то не понял?
> Фактически, нужны только Perl и программа gs, которые есть практически везде.
Ну, perl я у себя на рабочей Windows XP нашел :), а с gs вот так вот с ходу проблема. Никогда не задавался целью, правда, эту gs как-то использовать.
>Нам понадобится (кроме головы и рук) только работающий web-сервер с поддержкой cgi-bin, к которому у нас есть доступ по FTP
FTP — это опечатка ( м.б. HTTP? ), или же я чего-то не понял?
> Фактически, нужны только Perl и программа gs, которые есть практически везде.
Ну, perl я у себя на рабочей Windows XP нашел :), а с gs вот так вот с ходу проблема. Никогда не задавался целью, правда, эту gs как-то использовать.
Скрипт будет работать на web-сервере (сервер действительно, по определению, поддерживает HTTP). Разместить скрипт на сервере — через протокол FTP. Не опечатка :-)
На рабочей машине Perl и gs не нужны. Так как скрипт работает на сервере, то нужны они именно на сервере. Именно поэтому и обещано, что «за 10 минут»
На рабочей машине Perl и gs не нужны. Так как скрипт работает на сервере, то нужны они именно на сервере. Именно поэтому и обещано, что «за 10 минут»
Даже кириллицу понимает?
А мне проще aptitude install cups-pdf.
аналог факса в 21м веке =)
кстати, выкладывайте версию на PHP интересно!
Спасибо автору! На днях попробую скриптик. Есть принтеры, драйвера на которые отсутствуют для win7/winvista, а печатать по сети они не дают без них.
кстати, есть похожий (частично) сервис — BlueMailCentral (я как-то ради интереса пользовался пару раз)
он тоже ставит в систему свой принтер, и когда вы посылаете документ на печать, он отсылается на их сервер
отличие в том, что печатается не pdf — документ реально печатают на бумаге,
и посылают в конверте по указанному вами адресу
он тоже ставит в систему свой принтер, и когда вы посылаете документ на печать, он отсылается на их сервер
отличие в том, что печатается не pdf — документ реально печатают на бумаге,
и посылают в конверте по указанному вами адресу
Такая штука может быть полезна для электронного документооборота. Например, у вас в формате MS Word есть куча документов. Вы их махом печатаете на Web-принтере, который закидывает эти документы в систему документохранения. А человек, ответственный за порядок в документохранении, затем добавляет заголовки, права и тому подобное.
Спасибо, работает на УРА!
а вот только нельзя ли сделать так, чтобы имена файлов сохраняемых на сервере, соответствовали именам файлам — оригиналам.
а вот только нельзя ли сделать так, чтобы имена файлов сохраняемых на сервере, соответствовали именам файлам — оригиналам.
есть ли gs для Windows? (веб-сервер поднят на рабочей машине с WinXP)
Прошу прощения, в первый раз плохо погуглил.
Последняя версия gs под Win есть здесь: pages.cs.wisc.edu/~ghost/doc/GPL/gpl864.htm
Однако, скрипт всё равно не работает, т.к. в perl для Windows не реализован pipe-open :( Вероятно, можно как-то решить эту проблему используя модуль Win32::Fork
Последняя версия gs под Win есть здесь: pages.cs.wisc.edu/~ghost/doc/GPL/gpl864.htm
Однако, скрипт всё равно не работает, т.к. в perl для Windows не реализован pipe-open :( Вероятно, можно как-то решить эту проблему используя модуль Win32::Fork
Можно еще давать пользователям доступ только к тем файлам, которые «распечатали» они сами, добавив пару строк кода:
if (!(-e "../pdf/".$ENV{'REMOTE_ADDR'}."/.htaccess"))
{
mkdir "../pdf/".$ENV{'REMOTE_ADDR'};
open (AF, "> ../pdf/".$ENV{'REMOTE_ADDR'}."/.htaccess");
print AF qq[Order allow,deny\nallow from 127.0.0.1 10.103.224.171 ].$ENV{'REMOTE_ADDR'};
close AF;
}
А сохранять файлы, соответственно, в директорию, имя которой равно ИПшнику пользователя.
if (!(-e "../pdf/".$ENV{'REMOTE_ADDR'}."/.htaccess"))
{
mkdir "../pdf/".$ENV{'REMOTE_ADDR'};
open (AF, "> ../pdf/".$ENV{'REMOTE_ADDR'}."/.htaccess");
print AF qq[Order allow,deny\nallow from 127.0.0.1 10.103.224.171 ].$ENV{'REMOTE_ADDR'};
close AF;
}
А сохранять файлы, соответственно, в директорию, имя которой равно ИПшнику пользователя.
Если кому-то интересно будет, а с чисткой кода из статьи возиться не хочется, то вот он:
#! /usr/bin/perl
use strict;
if (!defined($ENV{'CONTENT_TYPE'}) || $ENV{'CONTENT_TYPE'} ne "application/ipp") {
print "Content-Type: text/html\n\n";
print ":-)";
exit;
}
# $d - входные данные в виде строки
# $l - длина строки входных данных
# $i - текущая позиция разбора данных
# %a - разобранные атрибуты
my ($d, $l, $i, %a) = ("", 0, 0);
binmode STDIN;
$l += read(STDIN, $d, 4096, $l) while (!eof(STDIN));
parseRequest(\$d, \$l, \$i, \%a);
my $o = ""
. substr($d, 0, 2) # version
. chr(0x00) . chr(0x00) # status
. substr($d, 4, 4) # request
. chr(0x01) # attributes
. stringAttribute(0x47, "attributes-charset", "utf-8")
. stringAttribute(0x48, "attributes-natural-language", "en-us")
. chr(0x04) # attributes
. stringAttribute(0x42, "printer-name", "PDF")
. chr(0x03) # end
. chr(0x0a)
;
print "Content-Type: text/html\n";
print "Content-Length: " . length($o) . "\n";
print "\n";
print $o;
if (defined($a{'-status'}) && $a{'-status'} == 0x02 && $i < $l) {
my @t = localtime;
my $output = sprintf("../pdf/%04d%02d%02d-%02d%02d%02d.pdf", $t[5] + 1900, $t[4], $t[3], $t[2], $t[1], $t[0]);
if (open(P, "|-", "gs", "-q", "-dBATCH", "-dNOPAUSE", "-dSAFER", "-sDEVICE=pdfwrite", "-sOutputFile=$output", "-")) {
binmode P;
print P substr($d, $i);
close P;
}
}
sub parseRequest {
my ($d, $l, $i, $a) = @_;
return if $$i >= $$l - 2;
$$a{'-version'} = (ord(substr($$d, $$i, 1)) << 8) + ord(substr($$d, $$i + 1, 1)); $$i += 2;
return if $$i >= $$l - 2;
$$a{'-status'} = (ord(substr($$d, $$i, 1)) << 8) + ord(substr($$d, $$i + 1, 1)); $$i += 2;
return if $$i >= $$l - 4;
$$a{'-request'} = parseInt(substr($$d, $$i, 4)); $$i += 4;
return if $$i >= $$l - 1;
my $what = ord(substr($$d, $$i, 1)); $$i ++;
return parseAttributes($d, $l, $i, $a) if ($what == 0x01);
}
sub parseAttributes {
my ($d, $l, $i, $a) = @_;
while ($$i < $$l) {
my $what = ord(substr($$d, $$i, 1)); $$i ++;
return if ($what == 0x03);
return parseAttributes($d, $l, $i, $a) if ($what == 0x02);
return parseAttributes($d, $l, $i, $a) if ($what == 0x04);
return if $$i >= $$l - 2;
my $key_len = (ord(substr($$d, $$i, 1)) << 8) + ord(substr($$d, $$i + 1, 1)); $$i += 2;
return if $$i >= $$l - $key_len;
my $key = substr($$d, $$i, $key_len); $$i += $key_len;
return if $$i >= $$l - 2;
my $val_len = (ord(substr($$d, $$i, 1)) << 8) + ord(substr($$d, $$i + 1, 1)); $$i += 2;
return if $$i >= $$l - $val_len;
my $val = substr($$d, $$i, $val_len); $$i += $val_len;
$$a{$key} = $val;
}
}
sub parseInt {
my $v = shift;
my $l = length($v);
my $r = 0;
for (my $i = $l; $i > 0; $i --) {
$r += ( (1 << (($i - 1) * 8)) * ord(substr($v, $l - $i, 1)) );
}
$r -= 4294967296 if ($r >= 2147483648);
return $r;
}
sub stringLength {
my $s = shift;
my $l = length($s);
my $i1 = $l & 0xFF;
$l = ($l - $i1) >> 8;
my $i2 = $l & 0xFF;
return chr($i2) . chr($i1);
}
sub stringAttribute {
my ($type, $key, $val) = @_;
return chr($type) . stringLength($key) . $key . stringLength($val) . $val;
}Sign up to leave a comment.
Свой Web-PDF принтер за 10 минут