Puisque je télécharge souvent des livres électroniques au format PDF, parfois de bons livres n'ont pas de signets lors du téléchargement, et cela ne ressemble pas à une lecture entière, alors j'ai décidé d'écrire un gadget moi-même, analyser le texte dans un format spécifique en Un signet, puis enregistrez-le au format PDF.
L'idée globale est de copier les informations du répertoire des présentations ci-dessous Douban, JD.com, Dangdang et Amazon.
La structure du répertoire est la suivante:
La copie de code est la suivante:
Chapitre 1 Aperçu HTTP 3
1.1 Messager multimédia de Http-Internet 4
1.2 Client Web et serveur 4
1.3 Ressource 5
1.3.1 Type de support 6
1.3.2 URI 7
1.3.3 URL 7
1.3.4 urne 8
1.4 Transaction 9
1.4.1 Méthode 9
1.4.2 Code d'état 10
1.4.3 Les pages Web peuvent contenir plusieurs objets 10
1.5 Message 11
1.6 Connexion 13
Chaque ligne a des numéros de page et est séparé par des espaces.
Après le traitement, le résultat est:
La logique principale est:
La copie de code est la suivante:
Package org.fra.pdf.bussiness;
Importer java.io.bufferedReader;
Importer java.io.fileOutputStream;
Importer java.io.ioException;
import java.util.arraylist;
import java.util.hashmap;
Importer java.util.list;
import java.util.stack;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.inthashTable;
import com.itextpdf.text.pdf.pdfArray;
import com.itextpdf.text.pdf.pdfdictionary;
import com.itextpdf.text.pdf.pdfinDirectReference;
import com.itextpdf.text.pdf.pdfname;
import com.itextpdf.text.pdf.pdfnumber;
import com.itextpdf.text.pdf.pdfObject;
import com.itextpdf.text.pdf.pdfreader;
import com.itextpdf.text.pdf.pdfstamper;
import com.itextpdf.text.pdf.pdfstring;
import com.itextpdf.text.pdf.simpleBookmark;
classe publique addpdfoutlinefromtxt {
Private Stack <SoustlineInfo> parentoutLineStack = new Stack <SoustlineInfo> ();
public void createPDF (String destpdf, chaîne sourcepdf,
BufferedReader Bufread, INT Pattern) lève IOException,
DocumentException {
if (modèle! = addbookmarkConstants.reserved_old_outline
&& modèle! = addbookmarkConstants.reserved_none
&& modèle! = addbookmarkConstants.reserved_first_outline)
retour;
// Lire dans le fichier PDF
PDFREADER Reader = new PdFreader (SourcePdf);
List <hashmap <string, objet >> suintes = new ArrayList <hashmap <string, objet >> ();
if (Pattern == addbookmarkConstants.reserved_old_outline) {
OUTLINES.ADDALL (SimpleBookmark.getBookmark (Reader));
} else if (Pattern == addbookmarkConstants.reserved_first_outline) {
AddFirstoutLineRereservEdPDF (Outlines, Reader);
}
addbookmarks (bufread, contours, null, 0);
// Créer un nouveau Stamper
PdfStamper Stamper = new PdfStamper (lecteur, new FileOutputStream (
destpdf));
Stamper.Setoutlines (contours);
Stamper.Close ();
}
Addbookmarks privé vides (BufferedReader Bufread,
List <hashmap <string, objet >> contours,
Hashmap <String, Object> Preoutline, int Prelevel)
lance iOException {
String ContentFormatLine = NULL;
Bufread.mark (1);
if ((contentFormatline = bufread.readline ())! = null) {
FormattedBookMark Bookmark = ParseFormattedText (ContentFormatLine);
Hashmap <string, objet> map = parsebookmarktohashmap (signet);
int niveau = bookmark.getLevel ();
// Si n == m, alors il est de la même couche.
if (niveau == Prelevel) {
contours.add (map);
AddBookmarks (bufread, contours, map, niveau);
}
// Si n> m, alors il est certain que la ligne est l'enfant de la ligne précédente, un nouveau ArrayList pour enfants et ajouté à cette liste d'arrasse
else if (niveau> prelevel) {
List <hashmap <string, objet >> kids = new ArrayList <hashmap <string, objet >> ();
kids.add (carte);
preoutline.put ("enfants", enfants);
// Enregistrer les informations sur les enfants
parentoutLinestack.push (Nouveau OutlineInfo (pré-ligne, contours,
Prelevel));
AddBookmarks (Bufread, enfants, carte, niveau);
}
// Si n <m, alors cela signifie que l'enfant a été ajouté et retourné au niveau supérieur, et Bufread reviendra sur la ligne
else if (niveau <prelevel) {
bufread.reset ();
OUTlineInfo obj = parentoutLineStack.pop ();
addbookmarks (bufread, obj.getoutlines (), obj.getPreoutLine (),
obj.getPrelevel ());
}
}
}
Hashmap privé <chaîne, objet> parsebookmarktohashmap (
FormattedBookmark Bookmark) {
Hashmap <string, objet> map = new hashmap <string, object> ();
map.put ("title", bookmark.getTitle ());
map.put ("action", "goto");
map.put ("page", bookmark.getPage () + "fit");
carte de retour;
}
FormattedBookMark PARSEFORMATTETTERT (String ContentFormatline) {
FormattedBookmark Bookmark = new FormattedBookmark ();
String title = "";
String destpage = "";
// Lorsqu'il n'y a pas de numéro de page à la fin de la chaîne, c'est généralement le nom du livre, si le format est correct.
int lastSpaceIndex = contentFormatline.LastIndexof ("");
if (LastSpaceIndex == -1) {
title = contentFormatline;
destpage = "1";
} autre {
title = contentFormatline.SubString (0, LastSpaceIndex);
destpage = contentFormatline.SubString (LastSpaceIndex + 1);
}
String [] titresplit = title.split ("");
int dotCount = titresplit [0] .split ("//."). Longueur - 1;
Bookmark.setLevel (dotCount);
bookmark.setpage (destpage);
Bookmark.setTitle (titre);
Return Bookmark;
}
VOID privé addFirstoutLineRereservedPdf (
List <hashmap <string, objet >> contours, lecteur pdfreader) {
Pdfdictionary catalog = Reader.getCatalog ();
PdfObject obj = pdfreader.getpdfobjectrelease (catalogue
.get (pdfname.outlines));
// pas de signet
if (obj == null ||! obj.isdictionary ())
retour;
PDFDictionary OutlinesDictionary = (pdfdictionary) obj;
// Obtenez le premier signet
Pdfdictionary FirstOutline = (pdfdictionary) pdfreader
.getPdfObjectRelease (OutlineSdictionary.get (pdfname.First));
PdfString titleObj = firstoutline.getAsstring ((pdfname.title));
String title = titleObj.TouniCodeString ();
PdfArray dest = firstOutLine.getAsArray (pdfname.dest);
if (dest == null) {
PDFDictionary Action = (PDFDictionary) Pdfreader
.getPdfObjectRelease (FirstOutLine.get (pdfname.a));
if (action! = null) {
if (pdfname.goto.equals (pdfreader.getpdfobjectrelease (action
.get (pdfname.s)))) {
dest = (pdfArray) pdfreader.getpdfobjectrelease (action
.get (pdfname.d));
}
}
}
String deststr = parsedestString (dest, lecteur);
String [] decodestrsr = deststr.split ("");
int num = Integer.ValueOf (Decodestr [0]);
Hashmap <string, objet> map = new hashmap <string, object> ();
map.put ("titre", titre);
map.put ("action", "goto");
map.put ("page", num + "fit");
contours.add (map);
}
Private String PARSEDESTSTRING (PDFARRAY DET, PDFREADER READER) {
String deststr = "";
if (dest.issstring ()) {
deststr = dest.toString ();
} else if (dest.isname ()) {
deststr = pdfname.decodename (dest.toString ());
} else if (dest.isArray ()) {
Pages inthashtable = new inthashTable ();
int numpages = reader.getNumberofPages ();
pour (int k = 1; k <= numpages; ++ k) {
pages.put (reader.getPageOrigref (k) .getNumber (), k);
lecteur.releasepage (k);
}
deststr = MakebookmarkParam ((pdfArray) dest, pages);
}
retour deststr;
}
String privé MakebookmarkParam (pdfArray dest, pages inthashtable) {
StringBuffer s = new StringBuffer ();
PdfObject obj = dest.getpdfObject (0);
if (obj.isnumber ()) {
S.APPEND (((pdfnumber) obj) .IntValue () + 1);
} autre {
S.APPEND (pages.get (getNumber ((pdfindirectreference) obj)));
}
S.APPEND ('') .APPEND (dest.getpdfObject (1) .ToString (). substring (1));
pour (int k = 2; k <dest.size (); ++ k) {
S.APPEND ('') .APPEND (dest.getpdfObject (k) .toString ());
}
retour s.toString ();
}
private int getNumber (pdfindirectreference indirect) {
Pdfdictionary pdfobj = (pdfdictionary) pdfreader
.getPdfobjectrelease (indirect);
if (pdfobj.Contains (pdfname.type)
&& pdfobj.get (pdfname.type) .equals (pdfname.pages)
&& pdfobj.Contains (pdfname.kids)) {
PdfArray kids = (pdfArray) pdfobj.get (pdfname.kids);
indirect = (pdfindirectreference) kids.getpdfObject (0);
}
return indirect.getNumber ();
}
}