Question [Fonction]Lire les propriétés d'un fichier PDF
- Laurent Dardenne
- Auteur du sujet
- Hors Ligne
- Modérateur
-
- Messages : 6311
- Remerciements reçus 68
Elle utilise la dll spécialisée iTextSharp.dll ( v5.0.4), celle-ci permet de manipuler et créer des fichiers .pdf.
[code:1]
# load ITextSHarp.dll
$path=\"G:\PS\PDF\"
[System.Reflection.Assembly]::LoadFrom(\"$path\itextsharp.dll\"«»)
function New-PDFDocumentInformation{
#Lit les propriétés et metadonnées d'un fichier PDF
#
# Un fichier pdf contient une table des références (xref),
# celle-ci est toujours stockée en fin de fichier.
# Le chargement partiel du document peut donc prendre un certain temps...
#Dépendance : itextsharp.dll ( v5.0.4)
# sourceforge.net/projects/itextsharp/
param(
[ValidateNotNullOrEmpty()]
[Parameter(Position=0,Mandatory=$true,ValueFromPipeline = $true,ValueFromPipelineByPropertyName= $true)]
[Alias(\"PSPath\"«»)]
#Référence un chemin d'un système de fichiers ou une url : file://, http://, https://
[String] $Path
)
begin {$isForceToReadAll=$False}
process {
try
{
# Vérifie le type du chemin
#pour \"h:/\", \"h:\\" -> false
#pour \"htoto:/\", \"http://\" -> true
#pour \"htoto:\\", \"http:\\\"-> false
if (-not [Uri]::IsWellFormedUriString($Path,[UriKind]::Absolute))
{
#Transforme le path qui peut être relatif ou
# contenir une référence à un provider.
$Path=$ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path)
}
#Le constructeur gére l'inexistence du fichier.
$AccessFile = New-object iTextSharp.text.pdf.RandomAccessFileOrArray($Path)
Write-debug \"`tWait load Pdf : $path\"
#Charge partiellement en mémoire un document PDF
$reader = New-object iTextSharp.text.pdf.PdfReader($AccessFile, $isForceToReadAll)
Write-debug \"Next pdf file\"
# Construit un objet à partir des propriétés du pdf.
$PDFDocument=New-Object PSObject -Property @{
FileName=$_.FullName
NumberOfPages=$reader.NumberOfPages;
#Pas de méthode Clone sur un dictionnaire générique.
Info=$(
$hCopy=@{}
$reader.Info.GetEnumerator()|
Foreach {$hCopy.Add($_.Key,$_.Value) }
$hCopy
)
#Le fichier est altéré ?
Tampered=$reader.Tampered;
#Only the last version char is returned
PdfVersion=$reader.PdfVersion;
#encryption permissions
Permissions=$reader.Permissions;
#le fichier peut être complété ?
Appendable=$reader.Appendable;
#Metadonnées XMP.
#conversion [Byte[]] to String
MetaData=New-Object String(,$Reader.Metadata);
#Informations sur la page
PageSize=$reader.GetPageSize(1)
}
#Défini le type de l'objet personnalisé
$PDFDocument.PsObject.TypeNames[0] = \"PDFDocumentInfo\"
$PDFDocument
} catch {
$PSCmdlet.WriteError(
(New-Object System.Management.Automation.ErrorRecord(
$_.Exception,
\"PDFDocumentInfoUriOrPath\",
\"InvalidOperation\",
(\"{0} : {1}\" -f $MyInvocation.Mycommand.Name,$_.Exception.Message))
)
)
}
finally {
if ($reader -ne $null)
{ $reader.Close() }
if ($AccessFile -ne $null)
{ $AccessFile.Close() }
} #finally
} #process
} #New-PDFDocumentInformation
New-Alias New-PdfInfo New-PDFDocumentInformation -description \"Construit un objet contenant les metadonnées d'un fichier PDF.\"
[/code:1]
Un exemple de recherche et de création à partir de la documentation d'Oracle 11g (170 fichiers pdf) :
[code:1]
$files=\"G:\Oracle\Documentation\"
$PDFInfos=gci $files *.pdf -recurse | New-PDFDocumentInformation
$PDFInfos|Select Filename, @{n=\"Title\";e={$_.info.Title}}|Out-GridView
$PDFInfos|Where {$_.Info.Title -match \"(PL/SQL|Packages|SQL|Error|Booklist)\"}|Select Filename, @{n=\"Title\";e={$_.info.Title}}
[/code:1]
Quelques exemples de manipulation des informations :
[code:1]
$Pdf=$PDFInfos[0]
#Lecture à partir d'un site Web
#$pdf=\"laurent-dardenne.developpez.com/articles...werShell.pdf\"|
# New-PDFDocumentInformation
$Height=[iTextSharp.text.Utilities]::«»PointsToMillimeters($Pdf.PageSize.Height)
$Width=[iTextSharp.text.Utilities]::«»PointsToMillimeters($Pdf.PageSize.Width)
\"Format de page : $Width x $Height\"
[iTextSharp.text.pdf.PdfEncryptor]::GetPermissionsVerbose($reader.Permissions)
$x=[xml]$Pdf.MetaData
#Le champ MetaData contient des balises XMP.
#leur nom peuvent changer d'un fichier à l'autre...
#Pour $pdf -> Http
#$x.xmpmeta.rdf.description
#Pour $pdf -> Doc Oracle
$x.rdf.Description
$x.rdf.Description[0].Keywords
#ou
#$o.MetaData -match \"pdf:Keywords='(.*)'\" ; $Matches
#Format date UTC
$Dto=[DateTimeOffset]::«»Parse($x.rdf.Description[0].CreationDate)
$Dto.UtcDateTime
$Dto.LocalDateTime
[/code:1]<br><br>Message édité par: Laurent Dardenne, à: 28/09/10 12:49
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Robert Spina
- Hors Ligne
- Nouveau membre
-
- Messages : 4
- Remerciements reçus 0
Dans le cadre d'utilisation de la DLL iTextSharp pour la création d'un PDF
- créer un fichier PDF depuis des fichiers textes qui ont une mise en page uniquement texte (colonnes créées par un ensemble d'espaces , ensemble de caractères étoiles pour faire un trait horizontal ou caractère \"I\" pour le trait verticale etc ..).
Le problème est abordé sur ce site :
social.technet.microsoft.com/Forums/en-U...7-9021-9e9d639da30d/
dont la solution est correcte mais pour du texte non formaté à l'aide d'espace !
Car lorsqu'il y a plusieurs espaces consécutifs, ceux-ci sont remplacés dans le .pdf par des tabulations .. (peut-être là se trouve la source de résolution : paramétrer les tabulations à un espace pour ce traitement ?) ce qui décale les alignements verticaux. (Pas le même rendu qu'une édition de ces mêmes fichiers via l'imprimante CutePdf ou PDFCreator qui eux respectent cette mise en forme texte)
Si le but étant de conserver tous les caractères (surtout les espaces) contenus dans la ligne, quelle méthode iTextSharp utiliser en complément ou substitution de cette ligne :
[code:1]$line = New-Object itextsharp.text.Paragraph($_)[/code:1]
J'ai pas beaucoup lu d'exemples écrits en Powershell, qui font appel à : iTextSharp.dll
Un complément dans cette contribution serait appréciable, merci d'avance.<br><br>Message édité par: roberto, à: 26/11/11 19:01
\"Rien est plus important que tout\"
(en prononçant la liaison après \"rien\" ...)
Pièces jointes :
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Auteur du sujet
- Hors Ligne
- Modérateur
-
- Messages : 6311
- Remerciements reçus 68
roberto écrit:
A priori c'est la piste à suivre, voir ce postroberto écrit:
(peut-être là se trouve la source de résolution : paramétrer les tabulations à un espace pour ce traitement ?)
support.itextpdf.com/node/120
ou les commentaires de celui-ci :
www.mikesdotnetting.com/Article/82/iText...rases-and-Paragraphs
roberto écrit:
Pour de telle DLL il faut rechercher du code C# ou autre (Java), car il s'agit de comprendre le comportement avant de l'implémenter.<br><br>Message édité par: Laurent Dardenne, à: 26/11/11 19:01J'ai pas beaucoup lu d'exemples écrits en Powershell, qui font appel à : iTextSharp.dll
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Robert Spina
- Hors Ligne
- Nouveau membre
-
- Messages : 4
- Remerciements reçus 0
J'ai bien essayé (pendant des heures durant) de comprendre comment implémenter cette dll, mais sans succès : du fait quoique je puisse utiliser (ITextSharp.Text.Phrase, ...Chunk ou ...Paragraph)
rien n'y fait, les problèmes liés aux nombreux espaces <non repris> persistes... \"j'ai lâché l'affaire\"
et m'oriente vers PDFSharp (bien qu'encore plus \"opaque\" à mes yeux de novice) :
=> y a-t-il une aide PDFSharp à la portée des non initiés C# ?
La difficulté pour ceux qui abordent PowerShell sans connaître la plateforme dotNet (et le langage C# par exemple) c'est de savoir \"comment utiliser les classes\" issues de cette plateforme dans un script PowerShell !
Et ce malgré l'aide de la commande Get-Member, car sans doc. détaillée (c'est le cas ici pour ITexteSharp) ou adaptée à PowerShell cela reste une sacrée opération.
Heureusement qu'il y a beaucoup de contributeurs, en PowerShell (merci à eux
\"Rien est plus important que tout\"
(en prononçant la liaison après \"rien\" ...)
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Auteur du sujet
- Hors Ligne
- Modérateur
-
- Messages : 6311
- Remerciements reçus 68
A l'origine ce n'était pas vraiment l'objectif.La difficulté pour ceux qui abordent PowerShell sans connaître la plateforme dotNet (et le langage C# par exemple) c'est de savoir \"comment utiliser les classes\" issues de cette plateforme dans un script PowerShell !
Il faut déjà savoir comment procéder en C# afin de le porter en PS si c'est possible.
Un post dans un forum c# spécialisé peut peut-être t'aider.Pour le moment je n'ai pas le temps de t'aider.
Peux-tu nous communiquer un fichier d'exemple pour tester ton pb ?
Sinon il existe des objet COM avec PdfCreator, avec Office 2010 il reste possible de sauvegarder en PDF.
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Robert Spina
- Hors Ligne
- Nouveau membre
-
- Messages : 4
- Remerciements reçus 0
Je suis parti sur la piste de : System.Collections.Generic.List
pour générer caractère par caractère via un flux
Afin de pouvoir l'utiliser dans : System.Drawing.Printing.PrintDocument
\"Rien est plus important que tout\"
(en prononçant la liaison après \"rien\" ...)
Connexion ou Créer un compte pour participer à la conversation.
- Vous êtes ici :
-
Accueil
-
forum
-
PowerShell
-
Contributions à la communauté
- [Fonction]Lire les propriétés d'un fichier PDF