Создать PDF с печатью масштаба страницы нет

10528
Collin

Мне нужно сгенерировать PDF-документ, в котором для параметров печати масштабирования страницы установлено значение «Нет» или «Фактический размер»

Этот параметр в документе будет означать, что по умолчанию при открытии документа в Adobe Reader или другом приложении для чтения PDF будет «Не сжимать эту страницу, чтобы поместиться в поля принтера»

В Adobe Reader 10 параметр, которым я хотел бы управлять, находится в диалоговом окне «Печать» и «Параметры размера и обработки страницы» для параметра «Параметры размера». Мне бы хотелось, чтобы в документе по умолчанию использовался «Фактический размер», а не «Сокращать негабаритные страницы».

Я поговорил с моими источниками и протестировал создание / сохранение документа PDF в редакции Adobe Standard, и вы можете установить для свойств просмотра документа значение по умолчанию для этого точного свойства, и Adobe Reader выполнит его вместо использования по умолчанию Adobe Reader. который шинк

Я использую PDF Creator 1.5.0, чтобы «напечатать» документ pfd, который, кажется, позволяет применять PostScript к документу. Однако я мог бы использовать альтернативный принтер PDF, если он подходил для моей цели и имел эту опцию. Я не вижу никакой опции GUI в настройках PDF Creator для управления им.

Я почти уверен, что мог бы использовать ghostscript для применения свойства, но мне нужно знать, как это сделать.

Обновление : я смотрел на спецификацию Adobe pdf, и свойства документа, которые я ищу, похоже, находятся в спецификации PDF 1.6.

12.2 Предпочтения зрителя Запись ViewerPreferences в каталоге документа (см. 7.7.2, «Каталог документов») обозначает словарь предпочтений зрителя (PDF 1.2), определяющий способ представления документа на экране или в печати. Если такой словарь не указан, соответствующие читатели должны вести себя в соответствии со своими текущими настройками пользовательских настроек. Таблица 150 показывает содержание словаря предпочтений зрителя.

PrintScaling - (Необязательно; PDF 1.6) Параметр масштабирования страницы, который следует выбирать при отображении диалогового окна печати для этого документа. Допустимые значения: None, что означает отсутствие масштабирования страницы, и AppDefault, которое указывает масштабирование печати по умолчанию для соответствующего читателя. Если эта запись имеет нераспознанное значение, следует использовать AppDefault. Значение по умолчанию: AppDefault. Если диалоговое окно печати подавлено и его параметры предоставлены из какого-либо другого источника, эта запись тем не менее должна выполняться.

Это именно то, что я хочу контролировать с помощью стороннего программного обеспечения PDF-принтера или ghostscript. Я не эксперт PDF, и я не знаю, как это сделать.

Обновление : я разработал решение с использованием Pdf Creator и отредактировал решение в принятый ответ. Я также посмотрел на следующее, что имеет потенциал для приложений при использовании API для создания PDF.
Твердые документы pdf

itextpdf - также доступен в версии C #

2
Я много знаю о PDF и Ghostscript (по крайней мере, мне нравится так думать) ... но я не понимаю вашей проблемы, извините. Kurt Pfeifle 11 лет назад 0
Извините, я впервые пытаюсь комментировать, и мой браузер бесится, я продолжаю нажимать Enter. и теперь я не могу редактировать. Простой вопрос, я хочу, чтобы параметр ghostscript напротив -dPDFFitPage. Это можно сделать с помощью Adobe Standard ... но через графический интерфейс я не знаю, какое свойство устанавливать. 11 лет назад 0
Откройте PDF в Adobe Reader -> Печать -> посмотрите под заголовком «Размер страницы и обработка», посмотрите «Параметры размера», и обычно по умолчанию будет «Shink oversize Pages» (другие страницы просмотра PDF имеют похожую настройку, но для простоты я я придерживаюсь точных слов Adobe) хочу добавить опцию «фактический размер» в документ. Я знаю, что это возможно, потому что Adobe Standard (полный создатель) позволяет вам установить это, и это будет приветствоваться, когда вы открываете PDF в Adobe Reader. 11 лет назад 0
Как автор вопроса, вы всегда можете отредактировать его. Постарайтесь быть ясным и логичным. Начните с рассказа о том, какую версию программного обеспечения + вы используете в настоящее время, и чего вы хотите достичь. И вы должны сделать это до того, как его проголосуют или даже удалят ... В настоящее время вы начинаете с * "Мне нужно создать PDF ..." *, не сообщая, какое программное обеспечение вы используете. Затем вы продолжаете говорить о * «Параметры печати масштабирования страницы» * ... что совершенно не похоже на * «создать PDF» * - печать PDF - это функция средства просмотра PDF, а не генератора PDF. Kurt Pfeifle 11 лет назад 0
Я ценю ваши комментарии. Я должен попытаться перефразировать вопрос, но ... Это то, где это становится волосатым, потому что они связаны. Я хочу создать документ, который имеет свойство по умолчанию для этой конкретной опции, которое отображается только при попытке распечатать этот документ. Это возможно со стандартом Adobe и с -dPDFFitPage в ghost scrpt, но это делает неправильную настройку, я хочу противоположность подгонки страницы. Я хочу фактический размер. Я также знаю, что вы можете установить другие свойства, такие как «В каком представлении должен открываться документ PDF по умолчанию» ... во весь экран и т. Д. ... во время создания документа. благодарю вас. 11 лет назад 0
Пожалуйста, не добавляйте пояснения в качестве комментариев. Отредактируйте свой оригинальный вопрос. При необходимости напишите новую и полностью удалите старую версию. Кроме того, «просмотр по умолчанию» PDF-файла, о котором вы говорите, является лишь * рекомендацией * для зрителя - зрителю не нужно его уважать (и вы, как пользователь программы просмотра, можете переопределить его, указав своему зрителю всегда открывать PDF-файлы в другом режиме вы предпочитаете ...). Kurt Pfeifle 11 лет назад 0
Обратите внимание также, что PDFFitPage не делает то, что вы, кажется, думаете. Он масштабирует входящий PDF-файл так, чтобы он соответствовал разным медиа-размерам. В устройстве ghostscript pdfwrite нет ничего, что могло бы изменить поведение по умолчанию при просмотре PDF. На самом деле я не знаю ни одного способа сделать это. Если у вас есть файл PDF, для которого это возможно, то я предлагаю вам сделать его общедоступным, чтобы мы могли посмотреть на него. KenS 11 лет назад 1
Добро пожаловать на Superuser.sx! Ваш пост был перенесен сюда из [так]. Пожалуйста, зарегистрируйтесь также на этом сайте и убедитесь, что обе учетные записи связаны друг с другом (используя один и тот же OpenID), иначе вы не сможете комментировать или принимать ответы или редактировать свой вопрос. Martin Schröder 11 лет назад 0
@KenS спасибо за разъяснения по поводу -PDFFitPage. Мартин-Шредер предоставил точную спецификацию ISO, которую я хочу использовать. Однако я до сих пор не знаю, как это сделать. Я считаю, что это связано с использованием pdfMark, но не могу найти точно, как это сделать. Collin 11 лет назад 0
Добро пожаловать на Superuser.sx! Обычно мы не помещаем приветствие или "спасибо" в наших сообщениях. Хотя на первый взгляд это может показаться странным, это не признак отсутствия вежливости, а скорее часть наших попыток сделать все очень кратким. Оповещение является предпочтительным способом сказать «спасибо» пользователям, которые помогли вам. Martin Schröder 11 лет назад 0

2 ответа на вопрос

2
Martin Schröder

This should be possible by specifying /PrintScaling /None in the ViewerPreferences dict (see section 12.2 in ISO 32000-1:2008.

Update: Try this:

[ << /ViewerPreferences << /PrintScaling /None >> >> /PUT pdfmark 

See http://www.digipedia.pl/usenet/thread/1191/1835/

Update: From Poster
The final solution was to add the above postscript line into the postscript generated by PDF Creator using the "Actions" feature of PDF Creator. (Action Before Saving)

http://www.pdfforge.org/content/actions

I also used this link as inspiration for the action and looked at the preinstalled vbs scripts to figure out what needed to be done to add information to the convert to pdf postscript file.

PDFCreator Document View settings - It seems that a script similar to this used to be included in PdfCreator.

Anyway this is my final script that can be added to Pdf Creator to add the PrintScaling default property.

' SetPrintScalingNone.vbs script ' Author: Collin Kulbacki ' Version: 1.0.0.0 ' Date: Oct 18, 2012 ' Comment: This script Sets the ViewerPrefferences Print Scalling to none. Option Explicit Const AppTitle = "PDFCreator - SetPrintScallingNone" Const ForReading = 1, ForAppending = 8 Dim objArgs, objNetwork, section, ini, fso, f Dim fname, key, psFile, strTitle, printScalingFile Set objArgs = WScript.Arguments If objArgs.Count = 0 Then MsgBox "This script needs a parameter!", vbExclamation, AppTitle WScript.Quit End If fname = objArgs(0) Set ini = New IniFile ini.Load fName, true Set fso = CreateObject("Scripting.FileSystemObject") printScalingFile = fso.GetParentFolderName(fName) & "\" & GenerateGUID & ".ps" Set f = fso.OpenTextFile(printScalingFile, ForAppending, True) f.writeline "[ << /ViewerPreferences << /PrintScaling /None >> >> /PUT pdfmark" f.Close Set objNetwork = CreateObject("WScript.Network") set section = ini.AddSection(GenerateGUID) section.AddKey("SessionId").Value = " " section.AddKey("WinStation").Value = " " section.AddKey("UserName").Value = objNetwork.UserName section.AddKey("ClientComputer").Value = objNetwork.ComputerName section.AddKey("SpoolFileName").Value = printScalingFile section.AddKey("PrinterName").Value = " " section.AddKey("JobId").Value = " " section.AddKey("DocumentTitle").Value = "PrintScaling" ini.Save fName, true WScript.Quit Private Function GenerateGUID() GenerateGUID = Replace(Mid(CreateObject("Scriptlet.TypeLib").GUID, 2, 36), "-", "") End Function ' http://www.codeproject.com/Articles/21896/INI-Reader-Writer-Class-for-C-VB-NET-and-VBScript ' IniFile class used to read a nd write ini files by loading the file into memory Class IniFile 'List of IniSection objects keeps track of all the sections in the INI file Private m_pSections, OpenAsUnicode 'Public constructor Public Sub Class_Initialize() Set m_pSections = CreateObject("Scripting.Dictionary") m_pSections.CompareMode = vbTextCompare End Sub 'Returns an array of the IniSections in the IniFile Public Property Get Sections Sections = m_pSections.Items End Property 'Load IniFile object with existing INI Data Public Sub Load( ByVal sFileName, ByVal bAppend ) Dim intAsc1Chr, intAsc2Chr If Not bAppend Then RemoveAllSections() ' Clear the object... Dim objFSO : Set objFSO = CreateObject("Scripting.FileSystemObject") Dim tempsection : Set tempsection = Nothing 'Dim oReader : Set oReader = objFSO.OpenTextFile( sFileName,, , format ) Dim oReader, Stream Set Stream = objFSO.OpenTextFile(sFileName, 1, False) intAsc1Chr = Asc(Stream.Read(1)) intAsc2Chr = Asc(Stream.Read(1)) Stream.Close ' (255, 254 == FF, FE -> UniCode) Or (91, 0 == [ '\0' -> Widechar inf file from pdfcmon.dll) If (intAsc1Chr = 255 And intAsc2Chr = 254) Or (intAsc1Chr = 91 And intAsc2Chr = 0) Then OpenAsUnicode = True Else OpenAsUnicode = False End If Set oReader = objFSO.OpenTextFile( sFileName, 1, 0, OpenAsUnicode ) Dim regexsection : set regexsection = new regexp Dim regexkey : Set regexkey = new regexp Dim regexcomment : Set regexcomment = new regexp regexcomment.Pattern = "^([\s]*#.*)" regexcomment.Global = False regexcomment.IgnoreCase = True regexcomment.MultiLine = False ' Left for history 'regexsection.Pattern = "\[[\s]*([^\[\s].*[^\s\]])[\s]*\]" 'regexsection.Pattern = "^[\s]*\[[\s]*([^\[\s].*[^\s\]])[\s]*\][\s]*$" regexsection.Pattern = "^\s*\[\s*(.*[^\s])\s*\]\s*$" regexsection.Global = False regexsection.IgnoreCase = True regexsection.MultiLine = False regexkey.Pattern = "^\s*([^=\s]*)[^=]*=(.*)" regexkey.Global = False regexkey.IgnoreCase = True regexkey.MultiLine = False While Not oReader.AtEndOfStream Dim line : line = oReader.ReadLine() If line <> "" Then Dim m If regexcomment.Test(line) Then Set m = regexcomment.Execute(line) 'WScript.Echo("Skipping Comment " & m.Item(0).subMatches.Item(0) ) ElseIf regexsection.Test(line) Then Set m = regexsection.Execute(line) 'WScript.Echo("Adding section [" & m.Item(0).subMatches.Item(0) &"]" ) Set tempsection = AddSection( m.Item(0).subMatches.Item(0) ) ElseIf regexkey.Test(line) And Not tempsection Is Nothing Then Set m = regexkey.Execute(line) 'WScript.Echo("Adding Key ["& m.Item(0).subMatches.Item(0) &"]=["& m.Item(0).subMatches.Item(1) &"]" ) tempsection.AddKey( m.Item(0).subMatches.Item(0) ).Value = m.Item(0).subMatches.Item(1) ElseIf Not tempsection Is Nothing Then 'WScript.Echo("Adding Key ["& line &"]" ) tempsection.AddKey( line ) 'Else ' WScript.Echo("Skipping unknown type of data: " & line) End If End If Wend oReader.Close() End Sub 'Allows you to do a save the IniFile resident in memory to file Public Sub Save(ByVal sFileName, ByVal AsUnicode) Dim objFSO : Set objFSO = CreateObject("Scripting.FileSystemObject") Dim oWriter : Set oWriter = objFSO.CreateTextFile( sFileName, True, AsUnicode ) Dim s 'IniSection Dim k 'IniKey For Each s In Sections 'WScript.Echo("Writing Section: " & s.Name) oWriter.WriteLine("[" & s.Name & "]") For Each k In s.Keys If k.Value <> vbNullString Then 'WScript.Echo("Writing Key: "&k.Name&"="&k.Value) oWriter.WriteLine(k.Name & "="& k.Value ) Else 'WScript.Echo("Writing Key: "&k.Name) oWriter.WriteLine(k.Name) End if Next Next oWriter.Close() End Sub 'Returns the IniSection object associated with a section name Public Function GetSection(ByVal sSection ) Set GetSection = Nothing sSection = Trim(sSection) 'Trim spaces If Len( sSection ) <> 0 Then If m_pSections.Exists( sSection ) Then Set GetSection = m_pSections.Item(sSection) End If End If End Function ' Adds a section to the IniFile object, returns a IniSection object Public Function AddSection(ByVal sSection ) Set AddSection = Nothing If StrComp(TypeName(sSection),"IniSection",1) = 0 Then If Not sSection Is Nothing Then ' Only purpose is to be used by child to re-insert If Not sSection Is Nothing Then If Not m_pSections.Exists( sSection.Name ) Then Set m_pSections.Item( sSection.Name ) = sSection Set AddSection = sSection End If End If End If ElseIf StrComp(TypeName(sSection),"String",1) = 0 Then sSection = Trim(sSection) If Len( sSection ) <> 0 Then If m_pSections.Exists( sSection ) Then Set AddSection = m_pSections.Item(sSection) Else Dim s : Set s = New IniSection Call s.Init( Me, sSection ) Set m_pSections.Item(sSection) = s Set AddSection = s End If End If End If End Function ' Removes all existing sections (clears the object) Public Sub RemoveAllSections() Call m_pSections.RemoveAll() End Sub ' Remove a section by name or section object Public Function RemoveSection(ByVal Obj) RemoveSection = False If StrComp(TypeName(Obj),"IniSection",1) = 0 Then If Not Obj Is Nothing Then m_pSections.Remove(Obj.Name) RemoveSection = True End If ElseIf StrComp(TypeName(Obj),"String",1) = 0 Then RemoveSection = RemoveSection( GetSection(Obj) ) End If End Function ' Remove a key by section namd and key name Public Function RemoveKey(ByVal sSection, ByVal sKey) RemoveKey = False Dim s : Set s = GetSection(sSection) If Not s Is Nothing Then RemoveKey = s.RemoveKey( sKey ) End If End Function ' Returns a KeyValue in a certain section Public Function GetKeyValue(ByVal sSection, ByVal sKey ) GetKeyValue = vbNullString Dim s : Set s = GetSection(sSection) If Not s Is Nothing Then Dim k : Set k = s.GetKey(sKey) If Not k Is Nothing Then GetKeyValue = k.Value End If End If End Function ' Sets a KeyValuePair in a certain section Public Function SetKeyValue(ByVal sSection, ByVal sKey, ByVal sValue ) SetKeyValue = False Dim s : Set s = AddSection(sSection) If Not s Is Nothing Then Dim k : Set k = s.AddKey(sKey) If Not s Is Nothing Then k.Value = sValue SetKeyValue = True End If End If End Function ' Renames an existing section returns true on success, false if the section didn't exist or there was another section with the same sNewSection Public Function RenameSection(ByVal sSection, ByVal sNewSection) ' Note string trims are done in lower calls. RenameSection = False Dim s : Set s = GetSection(sSection) If Not s Is Nothing Then RenameSection = s.SetName(sNewSection) End If End Function ' Renames an existing key returns true on success, false if the key didn't exist or there was another section with the same sNewKey Public Function RenameKey(ByVal sSection, ByVal sKey, ByVal sNewKey) ' Note string trims are done in lower calls. RenameKey = False Dim s : Set s = GetSection(sSection) If Not s Is Nothing Then Dim k : Set k = s.GetKey(sKey) If Not k Is Nothing Then RenameKey = k.SetName(sNewKey) End If End If End Function End Class 'IniSection Class Class IniSection ' IniFile IniFile object instance Private m_pIniFile ' Name of the section Private m_sSection ' List of IniKeys in the section Private m_keys 'Friend constuctor so objects are internally managed Public Sub Class_Initialize Set m_pIniFile = Nothing m_sSection = "" Set m_keys = CreateObject("Scripting.Dictionary") m_keys.CompareMode = vbTextCompare End Sub ' Function only works once... Public Sub Init( ByVal oIniFile, ByVal sSection ) If m_pIniFile is Nothing Then Set m_pIniFile = oIniFile m_sSection = sSection End If End Sub 'Returns an array of the IniKeys in the IniFile Public Property Get Keys Keys = m_keys.Items End Property 'Returns the section name Public Property Get Name name = m_sSection End Property 'Set the section name 'Returns true on success, False if key already exists in the section Public Function SetName(ByVal sSection) SetName = False ' Default sSection = Trim(sSection) If Len( sSection ) <> 0 Then Dim s : Set s = m_pIniFile.GetSection(sSection) If Not s Is Me And Not s Is Nothing Then Exit Function Call m_pIniFile.RemoveSection(Me) m_sSection = sSection Call m_pIniFile.AddSection(Me) SetName = True End If End Function 'Returns the section name Public Function GetName() GetName = m_sSection End Function 'Adds a key to the IniSection object 'Returns Nothing on failure Public Function AddKey(ByVal sKey) Set AddKey = Nothing ' Is this a string or object of IniKey If StrComp(TypeName(sKey),"IniKey",1) = 0 Then ' Only purpose is to be used by child to re-insert If Not sKey Is Nothing Then If Not m_keys.Exists( sKey.Name ) Then Set m_keys.Item(sKey.Name) = sKey Set AddKey = sKey End If End If ElseIf StrComp(TypeName(sKey),"String",1) = 0 Then ' String was passed... sKey = Trim(sKey) If Len(sKey) <> 0 Then If m_keys.Exists( sKey ) Then Set AddKey = m_keys.Item(sKey) Else Dim k : Set k = New IniKey Call k.Init( Me, sKey ) Set m_keys.Item(sKey) = k Set AddKey = k End If End If End If End Function 'Returns a IniKey 'Returns Nothing on failure Public Function GetKey(ByVal sKey) Set GetKey = Nothing sKey = Trim(sKey) If Len(sKey) <> 0 Then If m_keys.Exists( sKey ) Then Set GetKey = m_keys.Item(sKey) End If End If End Function 'Removes all the keys in the section Public Sub RemoveAllKeys() Call m_keys.RemoveAll() End Sub 'Removes a single key by IniKey object by string or object Public Function RemoveKey(ByVal Obj) RemoveKey = False If StrComp(TypeName(Obj),"IniKey",1) = 0 Then If Not Obj Is Nothing Then m_keys.Remove(Obj.Name) RemoveKey = True End If ElseIf StrComp(TypeName(Obj),"String",1) = 0 Then RemoveKey = RemoveKey( GetKey(Obj) ) End If End Function End Class ' End of IniSection 'IniKey Class Class IniKey ' Name of the Key Private m_sKey ' Value associated Private m_sValue ' Pointer to the parent CIniSection Private m_pSection 'Friend constuctor so objects are internally managed Public Sub Class_Initialize m_sKey = "" m_sValue = "" Set m_pSection = Nothing End Sub 'Returns the key's parent IniSection Public Sub Init( ByVal oIniSection, ByVal sKey ) If m_pSection Is Nothing Then Set m_pSection = oIniSection m_sKey = sKey End If End Sub 'Returns the name of the Key Public Property Get Name name = m_sKey End Property ' 'Gets\Sets the value associated with the Key Public Property Let Value( strKeyValue ) m_sValue = strKeyValue End Property 'Gets\Sets the value associated with the Key Public Property Get Value() value = m_sValue End Property 'Sets the key name 'Returns true on success, fails if the section name sKeyName already exists Public Function SetName(ByVal sKey ) SetName = False sKey = Trim(sKey) If Len(sKey) <> 0 Then Dim s : Set s = m_pSection.GetKey(sKey) If Not s Is Me And Not s Is Nothing Then Exit Function Call m_pSection.RemoveKey(Me) ' Set our new name m_sKey = sKey ' Put our own object back Call m_pSection.AddKey(Me) SetName = True End If End Function ' Returns the current key name Public Function GetName() GetName = m_sKey End Function End Class 

I can't take credit for the ini file class used to parse the output from PdfCreator that was provided via the existing vbs scrips in PdfCreator.

1
KenS

Проверяя версию 9 ссылки pdfmark, я не вижу pdfmark, который влияет на настройки просмотра. Таким образом, вы не сможете достичь этого с помощью Ghostscript без изменения устройства pdfwrite.

Устройство ghostscript pdfwrite вообще не генерирует словарь ViewerPreferences в объекте Catalog, поэтому вам нужно добавить его.

Спасибо за информацию, возможно, ghostscript - это не та технология, о которой нужно спрашивать. Мои знания об этом крайне минимальны. Из моего понимания я подумал, что ghostscript использует ps2pdf, и казалось, что ps2pdf может добавлять / редактировать каталог. Но, как я уже сказал, я новичок в формате pdf / ghostscript и не могу понять, что такое синтаксис. Даже после прочтения этого. http://ghostscript.com/doc/current/Ps2pdf.htm#Orientation Collin 11 лет назад 0
@ Коллин: я считаю, что это может быть сделано на работу; смотрите обновление к моему ответу. Martin Schröder 11 лет назад 0
ps2pdf (хотя бы в одном воплощении с таким именем) - это просто скрипт, который вызывает Ghostscript. Если Ghostscript задействован, то все остальные будут использовать его, а не наоборот. Ghostscript является основной технологией. KenS 11 лет назад 0
Мартин, твой ответ - правильный путь сделать это с pdfmark, я полагаю, с одной маленькой проблемой. Как я уже сказал, Ghostscript не создает ViewerPreferences в словаре каталога, и, поскольку он создает каталог по мере необходимости (в конце процесса), вы не можете ничего добавить в словарь каталога в ходе работы. Насколько я понимаю, единственный способ сделать это с помощью Ghostscript - достать ваш любимый редактор и компилятор C и начать кодирование. Каталог написан в gdevpdf.c, pdf_close () примерно в строке 2421. KenS 11 лет назад 0

Похожие вопросы