-
Eirik Steira authored
Rename get/createPdfDocument to get/createDocument
Eirik Steira authoredRename get/createPdfDocument to get/createDocument
PdfDocument.java 7.17 KiB
package NTNU.IDATT1002.service;
import NTNU.IDATT1002.models.Image;
import NTNU.IDATT1002.models.ImageAlbum;
import NTNU.IDATT1002.models.Metadata;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.PdfWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
/**
* Class PdfDocument. Generates a pdf document displaying a given image album.
*
* @author Eirik Steira
* @version 1.0 22.03.20
*/
public class PdfDocument implements ImageAlbumDocument {
/**
* Height ratio satisfying a 16:9 ratio.
*/
private final double HEIGHT_RATIO = 5.3;
private ImageAlbum imageAlbum;
private Document document;
private String DESTINATION_FILE;
private String defaultTitle = "Album";
/**
* Standard fonts.
*/
private Font headerFont = new Font(Font.FontFamily.TIMES_ROMAN, 18,
Font.BOLD);
private Font subFont = new Font(Font.FontFamily.TIMES_ROMAN, 16,
Font.BOLD);
private Font smallFont = new Font(Font.FontFamily.TIMES_ROMAN, 12);
public PdfDocument(ImageAlbum imageAlbum, String DESTINATION_FILE) {
this.imageAlbum = imageAlbum;
this.DESTINATION_FILE = DESTINATION_FILE;
this.document = new Document();
}
public File getDocument() {
return new File(DESTINATION_FILE);
}
/**
* Create a new pdf document.
*/
public void createDocument() {
try {
generatePdfDocument();
} catch (IOException | DocumentException e) {
e.printStackTrace();
}
}
/**
* Try to generate a pdf document.
*
* @throws IOException
* @throws DocumentException
*/
private void generatePdfDocument() throws IOException, DocumentException {
PdfWriter.getInstance(document, new FileOutputStream(DESTINATION_FILE));
document.open();
addHeadlines();
addContent();
document.close();
}
/**
* Add default headlines to the document, ie document title, ownership and date.
*
* @throws DocumentException
*/
private void addHeadlines() throws DocumentException {
Paragraph headline = new Paragraph();
addEmptyLineTo(headline, 1);
headline.add(new Paragraph(defaultTitle, headerFont));
addEmptyLineTo(headline, 1);
headline.add(new Paragraph(
"Generated by: " + imageAlbum.getUser().getUsername() + ", "
+ new Date(),
smallFont));
addEmptyLineTo(headline, 2);
document.add(headline);
}
/**
* Add main content to the document. This entails image album meta and all images.
*
* @throws DocumentException
* @throws IOException
*/
private void addContent() throws DocumentException, IOException {
addImageAlbumMeta();
addImagesContainer();
}
/**
* Add image album meta to the document, such as title, user etc.
*
* @throws DocumentException
*/
private void addImageAlbumMeta() throws DocumentException {
Paragraph imageAlbumMeta = new Paragraph();
String imageAlbumMetaContent = formatImageAlbumMeta();
imageAlbumMeta.add(new Paragraph(
imageAlbumMetaContent,
smallFont));
addEmptyLineTo(imageAlbumMeta, 1);
document.add(imageAlbumMeta);
}
/**
* Add container to contain images and a headline.
*
* @throws DocumentException
* @throws IOException
*/
private void addImagesContainer() throws DocumentException, IOException {
Paragraph imagesContainer = new Paragraph();
imagesContainer.add(new Paragraph("Images:", subFont));
document.add(imagesContainer);
addAllImages();
}
/**
* Add all images in the album to the document.
*
* @throws IOException
* @throws DocumentException
*/
private void addAllImages() throws IOException, DocumentException {
for (Image image : imageAlbum.getImages())
addSingleImage(image);
}
/**
* Add a single image to the document.
*
* @param image the image to add.
* @throws IOException
* @throws DocumentException
*/
private void addSingleImage(Image image) throws IOException, DocumentException {
com.itextpdf.text.Image displayImage = getImageFileFromBytes(image.getRawImage());
scaleImage(displayImage);
document.add(displayImage);
addImageMetaData(image);
}
/**
* Convert an array of bytes to {@link com.itextpdf.text.Image}.
*
* @param imageBytes the array of bytes to convert
* @return the image to display
* @throws IOException
* @throws BadElementException
*/
private com.itextpdf.text.Image getImageFileFromBytes(byte[] imageBytes)
throws IOException, BadElementException {
return com.itextpdf.text.Image.getInstance(imageBytes);
}
/**
* Scale given {@link com.itextpdf.text.Image image} to stretch
* half the width of the page, remaining a 16:9 ratio.
*
* @param image the image to scale
*/
private void scaleImage(com.itextpdf.text.Image image) {
float documentWidth = PageSize.A4.getWidth() - 2 * PageSize.A4.getBorder();
float scaledHeight = (float) (documentWidth / 2 * HEIGHT_RATIO);
image.scaleToFit(documentWidth / 2, scaledHeight);
}
/**
* Add an images metadata to the document.
*
* @param image the image holding the metadata
* @throws DocumentException
*/
private void addImageMetaData(Image image) throws DocumentException {
Metadata metadata = image.getMetadata();
if (metadata != null)
document.add(new Paragraph(metadata.toString()));
}
/**
* Format the album meta.
*
* @return the formatted album
*/
private String formatImageAlbumMeta() {
return new StringBuilder()
.append("Title: ")
.append(imageAlbum.getTitle())
.append("\n")
.append("User: ")
.append(imageAlbum.getUser().getUsername())
.append("\n")
.append("Created at: ")
.append(imageAlbum.getCreatedAt())
.append("\n")
.append("Description: ")
.append(imageAlbum.getDescription())
.append("\n")
.append("Tags: ")
.append(formatTags())
.toString();
}
/**
* Format the albums tags, separated by a comma.
*
* @return the formatted tags
*/
private String formatTags() {
StringBuilder tags = new StringBuilder();
imageAlbum.getTags().forEach(tag -> tags.append(tag.getName()).append(", "));
return tags.toString();
}
/**
* Add an empty line to the document.
*
* @param paragraph the paragraph to insert an empty line into
* @param number the number of empty lines desired
*/
private void addEmptyLineTo(Paragraph paragraph, int number) {
for (int i = 0; i < number; i++) {
paragraph.add(new Paragraph(" "));
}
}
}