This commit is contained in:
NicolasLACROIX 2019-11-01 19:27:14 +01:00
parent d53bf32b7c
commit d67f1c65cc
2 changed files with 174 additions and 200 deletions

View File

@ -0,0 +1,10 @@
package GenerateurPdf;
public class IncorrectFormatException extends Exception {
private static final long serialVersionUID = 1L;
public IncorrectFormatException(String errorMessage) {
super(errorMessage);
}
}

View File

@ -32,27 +32,19 @@ public class SubjectGenerator {
private int height;
private int width;
public SubjectGenerator(Config c, PDDocument doc, PDRectangle format) {
this.config = c;
this.pdDocument = doc;
this.format = format;
this.height = (int) Math.floor(format.getHeight());
this.width = (int) Math.floor(format.getWidth());
}
public SubjectGenerator(Config c, int nbPages, PDRectangle format) {
public SubjectGenerator(Config c) {
this.config = c;
this.pdDocument = new PDDocument();
this.format = format;
this.height = (int) Math.floor(format.getHeight());
this.width = (int) Math.floor(format.getWidth());
for (int i = 0; i < nbPages; i++) {
try {
this.format = SubjectGenerator.getFormatFromString(c.getParam().get("PaperSize"));
} catch (IncorrectFormatException ife) {
System.out.println("Format non reconnu. Format défini par défaut sur A4");
this.format = PDRectangle.A4;
}
this.pdDocument.addPage(new PDPage(this.format));
}
}
this.height = (int) this.format.getHeight();
this.width = (int) this.format.getWidth();
public SubjectGenerator() {
this(null, null, null);
}
public Config getConfig() {
@ -95,6 +87,27 @@ public class SubjectGenerator {
this.width = width;
}
public static PDRectangle getFormatFromString(String format) throws IncorrectFormatException {
switch (format) {
case "A0":
return PDRectangle.A0;
case "A1":
return PDRectangle.A1;
case "A2":
return PDRectangle.A2;
case "A3":
return PDRectangle.A3;
case "A4":
return PDRectangle.A4;
case "A5":
return PDRectangle.A5;
case "A6":
return PDRectangle.A6;
default:
throw new IncorrectFormatException("Le format spécifié n'est pas supporté.");
}
}
public static void drawDotedLine(PDPageContentStream pdPageContentStream, int xi, int yi, int xf, int yf)
throws IOException {
pdPageContentStream.moveTo(xi, yi);
@ -102,7 +115,6 @@ public class SubjectGenerator {
pdPageContentStream.lineTo(i, yf);
pdPageContentStream.moveTo(i + 2, yf);
}
// contentStream.fill();
}
public static void drawCircle(PDPageContentStream pdPageContentStream, int cx, int cy, int r) throws IOException {
@ -116,7 +128,7 @@ public class SubjectGenerator {
pdPageContentStream.fill();
}
public static void writeText(PDPageContentStream pdPageContentStream, String text, int x, int y)
public static void writeText(PDPageContentStream pdPageContentStream, String text, float x, float y)
throws IOException {
pdPageContentStream.beginText();
pdPageContentStream.newLineAtOffset(x, y);
@ -124,6 +136,10 @@ public class SubjectGenerator {
pdPageContentStream.endText();
}
public static float getStrLenWithFont(String text, PDFont font, int fontSize) throws IOException {
return (font.getStringWidth(text) / 1000) * fontSize;
}
public void generateFooter() {
int nbTotal = this.pdDocument.getNumberOfPages();
int count = 1;
@ -137,12 +153,9 @@ public class SubjectGenerator {
int fontSize = 10;
pdPageContentStream.setFont(font, fontSize);
String footer = String.valueOf(count) + " / " + String.valueOf(nbTotal);
float titleWidth = (font.getStringWidth(footer) / 1000) * fontSize;
float titleWidth = SubjectGenerator.getStrLenWithFont(footer, font, fontSize);
float titleHeight = (font.getFontDescriptor().getFontBoundingBox().getHeight() / 1000) * fontSize;
pdPageContentStream.beginText();
pdPageContentStream.newLineAtOffset((width - titleWidth) / 2, (35 - titleHeight));
pdPageContentStream.showText(footer);
pdPageContentStream.endText();
SubjectGenerator.writeText(pdPageContentStream, footer, (width - titleWidth) / 2, (35 - titleHeight));
pdPageContentStream.close();
count++;
}
@ -180,10 +193,8 @@ public class SubjectGenerator {
SubjectGenerator.drawCircle(pdPageContentStream, this.width - 20, 30, 5); // bottom right
// number (top of page) +n/n/nn+
pdPageContentStream.beginText();
pdPageContentStream.newLineAtOffset((this.width / 2) + 86, this.height - 30);
pdPageContentStream.showText("+" + digA + "/" + digB + "/" + digC + "+");
pdPageContentStream.endText();
SubjectGenerator.writeText(pdPageContentStream, "+" + digA + "/" + digB + "/" + digC + "+",
(this.width / 2) + 86, this.height - 30);
pdPageContentStream.close();
@ -237,10 +248,7 @@ public class SubjectGenerator {
pdPageContentStream.addRect(this.width - 238, this.height - 196, 155, 50); // RECT
// text
pdPageContentStream.beginText();
pdPageContentStream.newLineAtOffset(this.width - 236, this.height - 156);
pdPageContentStream.showText("Ecrivez votre Nom");
pdPageContentStream.endText();
SubjectGenerator.writeText(pdPageContentStream, "Ecrivez votre Nom", this.width - 236, this.height - 156);
// dot lines
// TODO: Enleve car difficulte d'ocr du fait de la presence des pointilles
@ -275,17 +283,12 @@ public class SubjectGenerator {
// num rectangle
pdPageContentStream.addRect(this.width / 4, this.height - 146, 150, 40);
pdPageContentStream.beginText();
pdPageContentStream.newLineAtOffset((this.width / 4) + 2, this.height - 115);
pdPageContentStream.showText("Ecrivez votre Numéro d'étudiant");
pdPageContentStream.endText();
String numEtudCons = Config.clearString(this.config.getParam().get("MarkField"));
SubjectGenerator.writeText(pdPageContentStream, numEtudCons, (this.width / 4) + 2, this.height - 115);
// note rectangle
pdPageContentStream.addRect(this.width / 4, this.height - 200, 150, 40);
pdPageContentStream.beginText();
pdPageContentStream.newLineAtOffset((this.width / 4) + 2, this.height - 170);
pdPageContentStream.showText("Note");
pdPageContentStream.endText();
SubjectGenerator.writeText(pdPageContentStream, "Note", (this.width / 4) + 2, this.height - 170);
pdPageContentStream.moveTo((this.width / 4) + 75, this.height - 160);
pdPageContentStream.lineTo((this.width / 4) + 75, this.height - 200);
@ -318,17 +321,13 @@ public class SubjectGenerator {
// draw first range of rectangles
pdPageContentStream.addRect(80 + (22 * i), this.height - 107, 11, 11);
// write first range of numbers
pdPageContentStream.beginText();
pdPageContentStream.newLineAtOffset(80 + (22 * i) + 12, this.height - 105);
pdPageContentStream.showText(String.valueOf(i));
pdPageContentStream.endText();
SubjectGenerator.writeText(pdPageContentStream, String.valueOf(i), 80 + (22 * i) + 12,
this.height - 105);
// draw second range of rectangles
pdPageContentStream.addRect(80 + (22 * i), this.height - 124, 11, 11);
// write second range of numbers
pdPageContentStream.beginText();
pdPageContentStream.newLineAtOffset(80 + (22 * i) + 12, this.height - 122);
pdPageContentStream.showText(String.valueOf(i));
pdPageContentStream.endText();
SubjectGenerator.writeText(pdPageContentStream, String.valueOf(i), 80 + (22 * i) + 12,
this.height - 122);
}
pdPageContentStream.close();
@ -338,7 +337,6 @@ public class SubjectGenerator {
}
public void generateHeader() {
// TODO: change text considering config data
try {
PDPage page = this.pdDocument.getPage(0);
@ -358,53 +356,34 @@ public class SubjectGenerator {
// Sujet
// center text : https://stackoverflow.com/a/6531362
String subject = "Exemple PT S3T : de 1970 à lan 2000, 30 ans dhistoire";
// String subject = "Exemple PT S3T : de 1970 à lan 2000, 30 ans dhistoire";
String subject = Config.clearString(this.config.getParam().get("Title"));
int fontSize = 12;
pdPageContentStream.setFont(font, fontSize);
float titleWidth = (font.getStringWidth(subject) / 1000) * fontSize;
float titleWidth = SubjectGenerator.getStrLenWithFont(subject, font, fontSize);
float titleHeight = (font.getFontDescriptor().getFontBoundingBox().getHeight() / 1000) * fontSize;
pdPageContentStream.beginText();
pdPageContentStream.newLineAtOffset((this.width - titleWidth) / 2, (this.height - 57 - titleHeight));
pdPageContentStream.showText(subject);
pdPageContentStream.endText();
String subtitle = "Tricherie : Toutes consultations de sources numériques sont interdites !!";
titleWidth = (font.getStringWidth(subtitle) / 1000) * fontSize;
pdPageContentStream.beginText();
pdPageContentStream.newLineAtOffset((this.width - titleWidth) / 2, (this.height - 71 - titleHeight));
pdPageContentStream.showText(subtitle);
pdPageContentStream.endText();
SubjectGenerator.writeText(pdPageContentStream, subject, (this.width - titleWidth) / 2,
(this.height - 57 - titleHeight));
// String subtitle = "Tricherie : Toutes consultations de sources numériques
// sont interdites !!";
String subtitle = Config.clearString(this.config.getParam().get("Presentation"));
titleWidth = SubjectGenerator.getStrLenWithFont(subtitle, font, fontSize);
SubjectGenerator.writeText(pdPageContentStream, subtitle, (this.width - titleWidth) / 2,
(this.height - 71 - titleHeight));
fontSize = 10;
// 1st line
pdPageContentStream.setFont(font, fontSize);
String numConsignePart1 = " Veuillez coder votre numéro";
titleWidth = (font.getStringWidth(numConsignePart1) / 1000) * fontSize;
pdPageContentStream.beginText();
pdPageContentStream.newLineAtOffset(this.width - 224, this.height - 94 - titleHeight);
pdPageContentStream.showText(numConsignePart1);
pdPageContentStream.endText();
// 2nd line
String numConsignePart2 = " détudiant ci-contre et écrire votre nom";
titleWidth = (font.getStringWidth(numConsignePart2) / 1000) * fontSize;
pdPageContentStream.beginText();
pdPageContentStream.newLineAtOffset(this.width - 244, this.height - 105 - titleHeight);
pdPageContentStream.showText(numConsignePart2);
pdPageContentStream.endText();
// 3rd line
String numConsignePart3 = " dans la case ci-dessous.";
titleWidth = (font.getStringWidth(numConsignePart3) / 1000) * fontSize;
pdPageContentStream.beginText();
pdPageContentStream.newLineAtOffset(this.width - 244, this.height - 118 - titleHeight);
pdPageContentStream.showText(numConsignePart3);
pdPageContentStream.endText();
// String numConsignePart1 = " Veuillez coder votre numéro";
int heightOffset = this.height - 115;
String numConsigne = Config.clearString(this.config.getParam().get("StudentField"));
for (String consigne : SubjectGenerator.setTextOnMultLines(numConsigne, this.width - 200, this.pdDocument,
font, fontSize)) {
SubjectGenerator.writeText(pdPageContentStream, consigne, this.width - 238, heightOffset);
heightOffset -= 10;
}
pdPageContentStream.close();
this.generateNumEtudAreaBis();
@ -425,7 +404,6 @@ public class SubjectGenerator {
int qIndex = 1;
int heightOffset = 265;
int pageIndex = 0;
// System.out.println(this.config.getQuestions());
// pour chaque question
ArrayList<Question> questions = this.config.getQuestions();
// si les questions doivent etre melangees
@ -446,6 +424,7 @@ public class SubjectGenerator {
// si on depasse la longeur de la page
if (heightOffset > (this.height - 10)) {
pageIndex++; // on va a la page suivante
this.pdDocument.addPage(new PDPage(this.format)); // on cree une nouvelle page
heightOffset = 55; // on se place en haut de la page
}
}
@ -471,34 +450,22 @@ public class SubjectGenerator {
PDFont font = PDType1Font.TIMES_ROMAN;
int fontSize = 10;
pdPageContentStream.setFont(font, fontSize);
float titleLength = (font.getStringWidth(q.getTitre()) / 1000) * fontSize;
// System.out.println(qIndex + ". " + q.getTitre() + " - Width: " + titleLength
// + "/" + this.width + " - " + this.height + " - NbRep: " +
// q.getReponses().size() + "\n");
float titleLength = SubjectGenerator.getStrLenWithFont(q.getTitre(), font, fontSize);
// Titre
// Si titre plus long que largeur page -> mise sur plusieurs lignes
// TODO: revoir structure (factorisation possible)
if (titleLength > (this.width - 20)) {
pdPageContentStream.beginText();
pdPageContentStream.newLineAtOffset(widthOffset, this.height - heightOffset);
pdPageContentStream.showText("Q." + qIndex + " -");
pdPageContentStream.endText();
// TODO: replace Q by config data
SubjectGenerator.writeText(pdPageContentStream, "Q." + qIndex + " - ", widthOffset,
this.height - heightOffset);
for (String line : setTextOnMultLines(q.getTitre(), widthOffset, pdDocument, font, fontSize)) {
pdPageContentStream.beginText();
pdPageContentStream.newLineAtOffset(widthOffset + 22, this.height - heightOffset);
pdPageContentStream.showText(line);
pdPageContentStream.endText();
// System.out.println("\n" + line + "\n");
SubjectGenerator.writeText(pdPageContentStream, line, widthOffset + 22, this.height - heightOffset);
heightOffset += 20;
}
} else {
pdPageContentStream.beginText();
pdPageContentStream.newLineAtOffset(widthOffset, this.height - heightOffset);
pdPageContentStream.showText("Q." + qIndex + " - " + q.getTitre());
pdPageContentStream.endText();
SubjectGenerator.writeText(pdPageContentStream, "Q." + qIndex + " - " + q.getTitre(), widthOffset,
this.height - heightOffset);
}
ArrayList<Reponse> reponses = q.getReponses();
@ -508,15 +475,9 @@ public class SubjectGenerator {
}
// pour chaque reponse
for (Reponse r : reponses) {
/**
* if (heightOffset > (this.height - 10)) { pageIndex++; // on va a la page
* suivante heightOffset = 55; // on se place en haut de la page }
*/
// on ecrit la reponse
pdPageContentStream.beginText();
pdPageContentStream.newLineAtOffset(widthOffset + 40, this.height - heightOffset - 15);
pdPageContentStream.showText(r.getIntitule());
pdPageContentStream.endText();
SubjectGenerator.writeText(pdPageContentStream, r.getIntitule(), widthOffset + 40,
this.height - heightOffset - 15);
// on ajoute une zone pour cocher (carre)
pdPageContentStream.addRect(widthOffset + 20, this.height - heightOffset - 16, 10, 10);
// si l'on souhait generer le corrige
@ -532,19 +493,8 @@ public class SubjectGenerator {
}
heightOffset += 17.5;
}
pdPageContentStream.close();
/*
* pdPageContentStream.beginText(); pdPageContentStream.newLineAtOffset(80 + (22
* * i) + 12, height - 105); pdPageContentStream.showText(String.valueOf(i));
* pdPageContentStream.endText(); // draw second range of rectangles
* pdPageContentStream.addRect(80 + (22 * i), height - 124, 11, 11); // write
* second range of numbers pdPageContentStream.beginText();
* pdPageContentStream.newLineAtOffset(80 + (22 * i) + 12, height - 122);
* pdPageContentStream.showText(String.valueOf(i));
* pdPageContentStream.endText();
*/
} catch (IOException ioe) {
ioe.printStackTrace();
}
@ -558,32 +508,44 @@ public class SubjectGenerator {
PDFont font = PDType1Font.TIMES_ROMAN;
int fontSize = 10;
pdPageContentStream.setFont(font, fontSize);
float titleLength = (font.getStringWidth(q.getTitre()) / 1000) * fontSize;
float titleLength = SubjectGenerator.getStrLenWithFont(q.getTitre(), font, fontSize);
float lastLineLenght = titleLength;
if (titleLength > (this.width - 20)) {
SubjectGenerator.writeText(pdPageContentStream, "Q." + qIndex + " - ", widthOffset,
this.height - heightOffset);
System.out.println("\nTITRE : " + q.getTitre() + "\n");
for (String line : setTextOnMultLines(q.getTitre(), widthOffset, pdDocument, font, fontSize)) {
SubjectGenerator.writeText(pdPageContentStream, line, widthOffset + 22, this.height - heightOffset);
heightOffset += 20;
lastLineLenght = (font.getStringWidth(line) / 1000) * fontSize;
lastLineLenght = SubjectGenerator.getStrLenWithFont(line, font, fontSize);
}
} else {
SubjectGenerator.writeText(pdPageContentStream, "Q." + qIndex + " - " + q.getTitre(), widthOffset,
this.height - heightOffset);
heightOffset += 20;
}
// on cherche a savoir a partir d'ou on peut mettre le texte pour etre le plus a
// droite possible en fonction du nombre de reponses associees
int maxX = this.width - widthOffset;
for (Reponse r : q.getReponses()) {
if ((titleLength + 16) > (this.width - 20)) {
SubjectGenerator.writeText(pdPageContentStream, r.getIntitule(), widthOffset + 20,
this.height - heightOffset - 15);
pdPageContentStream.addRect(widthOffset + 20, this.height - heightOffset - 16, 10, 10);
maxX -= SubjectGenerator.getStrLenWithFont(r.getIntitule(), font, fontSize);
// qu'occupe la case a
// cocher associee
}
// on affiche les reponses et les cases a cocher associees
// int varWidthOffset = widthOffset;
for (Reponse r : q.getReponses()) {
if ((lastLineLenght + 5) > maxX) {
pdPageContentStream.addRect(maxX, this.height - heightOffset, 10, 10);
SubjectGenerator.writeText(pdPageContentStream, r.getIntitule(), maxX + 12,
this.height - heightOffset);
} else {
SubjectGenerator.writeText(pdPageContentStream, r.getIntitule(),
widthOffset + (int) lastLineLenght + 15, this.height - heightOffset - 15);
pdPageContentStream.addRect(widthOffset + (int) lastLineLenght, this.height - heightOffset - 16, 10,
10);
pdPageContentStream.addRect(maxX, (this.height - heightOffset) + 20, 10, 10);
SubjectGenerator.writeText(pdPageContentStream, r.getIntitule(), maxX + 12,
(this.height - heightOffset) + 20);
}
if (isCorrected) {
// si c'est une bonne reponse
@ -595,19 +557,22 @@ public class SubjectGenerator {
} else {
pdPageContentStream.stroke(); // carre vide
}
maxX += SubjectGenerator.getStrLenWithFont(r.getIntitule(), font, fontSize) + 20;
}
heightOffset += 17.5;
// zone d'ecriture (rectangle)
// TODO: ameliorer
int widthMargin = 60;
int linesLenght = q.getNbligne() * 20; // 20 = taille d'une ligne
int yLenght = (this.width - widthOffset - widthMargin);
pdPageContentStream.addRect(widthOffset + 20, this.height - heightOffset - 16, yLenght, linesLenght);
int yLenght = (this.width - widthMargin);
pdPageContentStream.addRect(widthOffset + 20, this.height - heightOffset - 10, yLenght, linesLenght);
int yCursor = this.height - heightOffset - 16;
for (int i = 0; i < q.getNbligne(); i++) {
yCursor = this.height - heightOffset - 16 - (i * 2); // on descends y de la taille d'une ligne
// SubjectGenerator.drawDotedLine(pdPageContentStream, xi, widthOffset + 30, xf,
// yLenght);
// SubjectGenerator.drawDotedLine(pdPageContentStream, widthOffset + 23,
// this.height - heightOffset - (20 * i), yLenght - 23, this.height -
// heightOffset - (20 * i));
}
pdPageContentStream.close();
@ -618,61 +583,60 @@ public class SubjectGenerator {
public static ArrayList<String> setTextOnMultLines(String text, int widthOffset, PDDocument pdDocument, PDFont font,
int fontSize) {
// TODO: voir si l'on laisse en static ou non
float subStrLength = 0;
int width = (int) pdDocument.getPage(0).getMediaBox().getWidth();
ArrayList<String> lines = new ArrayList<String>();
int widthMargin = 60;
int lastSpace = -2;
int spaceIndex = 0;
while (text.length() > 0) {
// System.out.println("1. Si: " + spaceIndex + " - Ls: " + lastSpace + " TxtL: "
// + text.length());
spaceIndex = text.indexOf(' ', lastSpace + 2);
// System.out.println("2. Si: " + spaceIndex + " - Ls: " + lastSpace + " : " +
// text + "\n");
String subStr = "";
// System.out.println("1. SubL: " + subStrLength + " - W: " + (width -
// widthOffset));
ArrayList<String> lines = new ArrayList<>();
if (spaceIndex == -1) {
lines.add(text);
text = "";
} else {
subStr = text.substring(0, spaceIndex);
if (text.isBlank()) {
// si le texte est une chaine vide ou ne contenant que des espaces
return lines;
}
int widthMargin = 60;
int textSize = 0;
try {
subStrLength = (font.getStringWidth(subStr) / 1000) * fontSize;
textSize = (int) SubjectGenerator.getStrLenWithFont(text, font, fontSize); // taille totale du texte
} catch (IOException ioe) {
System.err.print(ioe.getMessage());
ioe.printStackTrace();
}
// System.out.println("2. SubL: " + subStrLength + " - W: " + (width -
// widthOffset));
int availableWidth = width - widthOffset - widthMargin; // largeur disponible (marge enlevee)
int index = 0;
if (subStrLength > (width - widthOffset - widthMargin)) {
if (lastSpace > 0) {
lastSpace = spaceIndex;
while (textSize > availableWidth) {
// tant que la taille du texte restant depasse en largeur
try {
while (SubjectGenerator.getStrLenWithFont(text.substring(0, index), font, fontSize) < availableWidth) {
// tant que la taille de la sous chaine de caractere ne depasse pas
index++;
System.out.println(index);
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
if (text.substring(0, index).endsWith(" ") || text.substring(0, index).endsWith("-")
|| text.substring(index, text.length() - 1).startsWith(" ")
|| text.substring(index, text.length() - 1).startsWith("-")) {
// System.out.println("[IF] SubL: " + subStrLength + " - W: " + (width -
// widthOffset));
subStr = text.substring(0, lastSpace);
lines.add(subStr);
text = text.substring(lastSpace).trim();
lastSpace = -1;
} else if (spaceIndex == lastSpace) {
lines.add(text);
text = "";
// System.out.println("LTxt: " + text.length());
lines.add(text.substring(0, index));
text = text.substring(index);
} else if (text.substring(0, index - 1).endsWith(" ") || text.substring(0, index - 1).endsWith("-")) {
lines.add(text.substring(0, index - 1));
text = text.substring(index - 1);
} else {
lastSpace = spaceIndex;
}
// sinon on coupe le mot
lines.add(text.substring(0, index - 1) + "-");
text = text.substring(index - 1);
}
try {
textSize = (int) SubjectGenerator.getStrLenWithFont(text, font, fontSize);
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
lines.add(text);
return lines;
}
@ -686,20 +650,20 @@ public class SubjectGenerator {
}
public static void main(String args[]) throws IOException {
Config c = new Config("E:\\source.txt");
c.readConfig();
// devra etre fait dans Exec
Config config = new Config("E:\\source.txt");
config.readConfig();
// -------------------------
// instanciate a new SubjectGenerator
// TODO: change PDRectangle.A4 to the format specified in the config
// TODO: number of page = automatic
SubjectGenerator subjectGenerator = new SubjectGenerator(c, 5, PDRectangle.A4);
SubjectGenerator subjectGenerator = new SubjectGenerator(config);
// ATTENTION : generateBody est place en premier car c'est elle qui va generer
// le nombre de page suffisant
subjectGenerator.generateBody(false); // false = on genere le sujet, pas le corrige
subjectGenerator.generateHeader();
subjectGenerator.generateMarks();
// subjectGenerator.generateNumEtudAreaBis();
// subjectGenerator.generateNameArea();
subjectGenerator.generateFooter();
subjectGenerator.generateBody(false); // false = on genere le sujet, pas le corrige
subjectGenerator.save("E:\\testPDFMarks.pdf");