Criar PDF com escala de página de impressão de nenhum

2

Eu preciso gerar um documento em pdf que tenha as Opções de impressão do escalonamento de página definidas como "Nenhum" ou "Tamanho real"

Essa configuração no documento significa que o padrão quando você abre o documento no Adobe Reader ou outro leitor de PDF será "Não encolha esta página para caber nas margens da impressora"

No Adobe Reader 10, a configuração que gostaria de controlar está na caixa de diálogo Imprimir e em "Tamanho de página e manipulação" da opção "Opções de tamanho". Gostaria que o documento fosse padronizado como "Tamanho real" em vez de "Encolher" páginas superdimensionadas ".

Conversei com minhas fontes e testei com a criação / salvamento de um documento PDF com a edição do Adobe Standard e você pode definir as propriedades de exibição do documento como padrão para essa propriedade exata e o Adobe Reader honrará isso em vez de usar o Padrão do Adobe Reader, que é shink.

Estou usando o PDF Creator 1.5.0 para "Imprimir" o documento pfd, que parece permitir que o postscript seja aplicado ao documento. No entanto, eu poderia usar uma impressora PDF alternativa se fosse adequado ao meu propósito e tivesse essa opção. Eu não vejo nenhuma opção GUI nas configurações do PDF Creator para controlá-lo.

Tenho certeza de que poderia usar o ghostscript para aplicar uma propriedade, mas preciso saber como fazer isso.

Atualização : Eu tenho procurado a especificação de pdf da Adobe e as propriedades do documento que estou procurando parecem estar na especificação do PDF 1.6.

12.2 Viewer Preferences The ViewerPreferences entry in a document’s catalogue (see 7.7.2, “Document Catalog”) designates a viewer preferences dictionary (PDF 1.2) controlling the way the document shall be presented on the screen or in print. If no such dictionary is specified, conforming readers should behave in accordance with their own current user preference settings. Table 150 shows the contents of the viewer preferences dictionary.

PrintScaling - (Optional; PDF 1.6) The page scaling option that shall be selected when a print dialog is displayed for this document. Valid values are None, which indicates no page scaling, and AppDefault, which indicates the conforming reader’s default print scaling. If this entry has an unrecognized value, AppDefault shall be used. Default value: AppDefault. If the print dialog is suppressed and its parameters are provided from some other source, this entry nevertheless shall be honored.

Isso é EXATAMENTE o que eu quero controlar por meio de algum software de impressora PDF de terceiros ou ghostscript. Eu não sou especialista em PDF e não sei como fazer isso.

Atualização : desenvolvi uma solução usando o PDF Creator e editei a solução na resposta aceita. Também observei o seguinte que tem potencial para aplicativos ao usar uma API para gerar o pdf. Solid Documents pdf

itextpdf - Também disponível em versão C #

    
por Collin 12.10.2012 / 23:25

2 respostas

2

Isso deve ser possível especificando /PrintScaling /None no ViewerPreferences dict (consulte a seção 12.2 em ISO 32000-1: 2008 .

Atualizar : Tente isto:

[ {Catalog} << /ViewerPreferences << /PrintScaling /None >> >> /PUT
pdfmark

Veja o link

Atualizar : From Poster
A solução final foi adicionar a linha postscript acima no postscript gerado pelo PDF Creator usando o recurso "Actions" do PDF Creator. (Ação antes de salvar)

link

Eu também usei este link como inspiração para a ação e examinei os scripts vbs pré-instalados para descobrir o que precisava ser feito para adicionar informações ao arquivo pdf convertido em postscript.

Configurações do PDFCreator Document View - Parece que um script semelhante a este costumava ser incluído no PdfCreator.

De qualquer forma, este é o meu script final que pode ser adicionado ao PDF Creator para adicionar a propriedade padrão PrintScaling.

' 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 "[ {Catalog} << /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 == [ '
[ {Catalog} << /ViewerPreferences << /PrintScaling /None >> >> /PUT
pdfmark
' -> 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

Não posso receber crédito pela classe de arquivo ini usada para analisar a saída do PdfCreator fornecida pelos scripts vbs existentes no PdfCreator.

    
por 14.10.2012 / 15:15
1

Verificando a versão 9 da referência do pdfmark, não consigo ver nenhum pdfmark que afete as Preferências do Viewer. Portanto, não há como você conseguir isso usando o Ghostscript sem modificar o dispositivo pdfwrite.

O dispositivo pdfwrite do Ghostscript não emite um dicionário ViewerPreferences no objeto Catalog, então você precisa adicionar um.

    
por 16.10.2012 / 09:18