Select Git revision
PdfDocument.java
-
Eirik Steira authored
Add HostService to Dataexchange to open files, add logic to save pdf to downloads folder and possibility to open it afterwards on the same button for generating it
Eirik Steira authoredAdd HostService to Dataexchange to open files, add logic to save pdf to downloads folder and possibility to open it afterwards on the same button for generating it
PdfDocument.java 7.14 KiB
package NTNU.IDATT1002.utils;
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 {
/**
* 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 getPdfDocument() {
return new File(DESTINATION_FILE);
}
/**
* Create a new pdf document.
*/
public void createPdfDocument() {
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(" "));
}
}
}