I have a serious problem with my footer generator. It has the function to describe one specific word from the page (I think that is called a footnote).
This function doesn't quite work yet, anyways. The problem is that my footer can have 1, all the way to 20 or something lines. And in most cases, it is overlapping with the text.
Here is the code of my footer creator:
Font fontTimes = FontFactory.getFont(FontFactory.TIMES_ROMAN, 10,
Font.NORMAL);
PdfPTable table = new PdfPTable(1);
table.getDefaultCell().setBorder(Rectangle.TOP);
table.addCell("all the descriptions.");
table.writeSelectedRows(0, -1, document.left(document.leftMargin()),
table.getTotalHeight() + document.bottom(document.bottomMargin()),
writer.getDirectContent());
The rest of the pages are just created with lists that contains paragraphs, they are just added in the document. And I use "onEndPage" to put the footer in every page.
Here is some of the code I use to create and write in the document:
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(this.fileStorageLocation.resolve(caminhoDoc) + File.separator + nomeDocumento + ".pdf"));
document.setPageSize(PageSize.A4);
document.setMargins(36, 36, 36, 55);
document.setMarginMirroring(false);
writer.setPageEvent(this);
//creating lists...
document.add(mainList);
The pdf is great, except the footer, that is overlapping the rest of the content. I am not sure how to fix it, I'm thinking that maybe the solution is to calculate the space that the footer will need, then set the specific page size to fit with that blank space for the footer.
Here is a small code sample to add footer dynamically to each page of the pdf using the PdfPageEventHelper interface
package com.asu.util;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.ServletContext;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Font.FontFamily;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.html.WebColors;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfWriter;
public class HeaderFooter extends PdfPageEventHelper {
/** Alternating phrase for the header. */
Phrase[] header = new Phrase[2];
/** Current page number (will be reset for every chapter). */
int pagenumber;
private ServletContext context;
private String domainName;
private String createdDate;
public HeaderFooter(ServletContext context, String reportType, String
createdDate, String domainName) {
this.context = context;
this.reportType = reportType;
this.createdDate = createdDate;
this.domainName = domainName;
// TODO Auto-generated constructor stub
}
/**
* Adds the footer.
*
* #see com.itextpdf.text.pdf.PdfPageEventHelper#onEndPage(com.itextpdf.text.pdf.PdfWriter,
* com.itextpdf.text.Document)
*/
public void onEndPage(PdfWriter writer, Document document) {
Image image;
Font fontStyle = new Font();
fontStyle.setColor(255, 255, 255);
fontStyle.setSize(6);
try {
image = Image.getInstance(context.getRealPath("template//images//footer1.png"));
int indentation = 0;
float scaler = ((document.getPageSize().getWidth() - indentation) / image.getWidth()) * 100;
image.scalePercent(scaler);
image.setAbsolutePosition(0, 0);
document.add(image);
} catch (Exception e) {
e.printStackTrace();
}
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-YYYY");
String date = sdf.format(new Date());
ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_CENTER,
new Phrase(String.format("Page - %d, Printed on : %s %s", pagenumber, date,
domainName), fontStyle),
(document.getPageSize().getWidth()) / 2, document.bottomMargin() - 28.5f, 0);
}
}
Then call the headerfooter onEndPage() from the pdf generation method
HeaderFooter headerFooter = new HeaderFooter(context, "reportType",
reportCreatedDate, domainName);
Related
To create tooltip I use the following code based on this answer.
Callback<TableColumn,TableCell> existingCellFactory = column.getCellFactory();
column.setCellFactory(c -> {
TableCell cell = existingCellFactory.call((TableColumn) c);
Tooltip tooltip = new Tooltip();
tooltip.textProperty().bind(cell.textProperty());
cell.tooltipProperty().bind(
Bindings.when(Bindings.or(cell.emptyProperty(), cell.itemProperty().isNull()))
.then((Tooltip) null).otherwise(tooltip));
return cell ;
});
The problem is that in this case when user moves mouse on table on any cell tooltip appears there and user gets too many tooltips.
How to show tooltip only on those table cells which text is wider cell width and replaced to "..." at the end?
Here is my attempt at solving this.
Note: I am using com.sun.javafx.scene.control.skin.Utils based on this answer. Some methods appear to be depreciated. This answer assumes you are using the default font.
This app checks each table cell of a table and determine if the text inside the cell is ellipsized. It makes use of a JavaFx Utility.
Main
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;
/**
*
* #author Sedrick
*/
public class JavaFXApplication5 extends Application {
private final TableView<Person> table = new TableView<>();
private final ObservableList<Person> data =
FXCollections.observableArrayList(new Person("A", "B"), new Person("ZZZZZZZZZZZZZZZZ","XXXXXXXXXXXXXXXX"), new Person("ZZZ", "XXX"));
final HBox hb = new HBox();
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
Scene scene = new Scene(new Group());
stage.setWidth(450);
stage.setHeight(550);
TableColumn firstNameCol = new TableColumn("First Name");
firstNameCol.setMinWidth(100);
firstNameCol.setCellValueFactory(
new PropertyValueFactory<>("firstName"));
TableColumn lastNameCol = new TableColumn("Last Name");
lastNameCol.setMinWidth(100);
lastNameCol.setCellValueFactory(
new PropertyValueFactory<>("lastName"));
table.setItems(data);
table.getColumns().addAll(firstNameCol, lastNameCol);
final Button addButton = new Button("Add");
addButton.setOnAction((ActionEvent e) -> {
data.add(new Person("ZZZZZZZZZZZZZZZZ","XXXXXXXXXXXXXXXX"));
data.add(new Person("ZZZ", "XXX"));
});
hb.getChildren().addAll(addButton);
hb.setSpacing(3);
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(10, 0, 0, 10));
vbox.getChildren().addAll(table, hb);
((Group) scene.getRoot()).getChildren().addAll(vbox);
stage.setScene(scene);
stage.show();
//ScenicView.show(scene);
//loop through all the table cells
for(TableColumn tableColumn : table.getColumns())
{
for(int i = 0; i < table.getItems().size(); i++)
{
System.out.println(tableColumn.getCellData(i) + " isCellEllipsized: " + isCellEllipsized(tableColumn.getWidth(), tableColumn.getCellData(i).toString()));
}
}
}
boolean isCellEllipsized(double tableColumnWidth, String cellData)
{
Text text = new Text(cellData);//Convert String to Text
double textActualWidth = text.getBoundsInLocal().getWidth();//Get the width of the Text object
double textComputedWidth = Utility.computeTextWidth(text.getFont(), cellData, tableColumnWidth);//Use the utility. It returns how long the text should be if it needs to be ellipsized and the actual text lengh if it does not need to be ellipsized.
return textActualWidth > textComputedWidth;
}
public static class Person {
private final SimpleStringProperty firstName;
private final SimpleStringProperty lastName;
private Person(String fName, String lName) {
this.firstName = new SimpleStringProperty(fName);
this.lastName = new SimpleStringProperty(lName);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String fName) {
firstName.set(fName);
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String fName) {
lastName.set(fName);
}
}
}
Utility Class
/*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
import java.text.Bidi;
import java.text.BreakIterator;
import static javafx.scene.control.OverrunStyle.*;
import javafx.application.Platform;
import javafx.application.ConditionalFeature;
import javafx.geometry.Bounds;
import javafx.geometry.HPos;
import javafx.geometry.Point2D;
import javafx.geometry.VPos;
import javafx.scene.control.OverrunStyle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.scene.text.TextBoundsType;
import com.sun.javafx.scene.text.HitInfo;
import com.sun.javafx.scene.text.TextLayout;
import com.sun.javafx.tk.Toolkit;
/**
* BE REALLY CAREFUL WITH RESTORING OR RESETTING STATE OF helper NODE AS LEFTOVER
* STATE CAUSES REALLY ODD NASTY BUGS!
*
* We expect all methods to set the Font property of helper but other than that
* any properties set should be restored to defaults.
*/
public class Utility {
static final Text helper = new Text();
static final double DEFAULT_WRAPPING_WIDTH = helper.getWrappingWidth();
static final double DEFAULT_LINE_SPACING = helper.getLineSpacing();
static final String DEFAULT_TEXT = helper.getText();
static final TextBoundsType DEFAULT_BOUNDS_TYPE = helper
.getBoundsType();
/* Using TextLayout directly for simple text measurement.
* Instead of restoring the TextLayout attributes to default values
* (each renders the TextLayout unable to efficiently cache layout data).
* It always sets all the attributes pertinent to calculation being performed.
* Note that lineSpacing and boundsType are important when computing the height
* but irrelevant when computing the width.
*
* Note: This code assumes that TextBoundsType#VISUAL is never used by controls.
* */
static final TextLayout layout = Toolkit.getToolkit()
.getTextLayoutFactory().createLayout();
static double getAscent(Font font, TextBoundsType boundsType) {
layout.setContent("", font.impl_getNativeFont());
layout.setWrapWidth(0);
layout.setLineSpacing(0);
if (boundsType == TextBoundsType.LOGICAL_VERTICAL_CENTER) {
layout.setBoundsType(TextLayout.BOUNDS_CENTER);
} else {
layout.setBoundsType(0);
}
return -layout.getBounds().getMinY();
}
static double getLineHeight(Font font, TextBoundsType boundsType) {
layout.setContent("", font.impl_getNativeFont());
layout.setWrapWidth(0);
layout.setLineSpacing(0);
if (boundsType == TextBoundsType.LOGICAL_VERTICAL_CENTER) {
layout.setBoundsType(TextLayout.BOUNDS_CENTER);
} else {
layout.setBoundsType(0);
}
return layout.getBounds().getHeight();
}
static double computeTextWidth(Font font, String text,
double wrappingWidth) {
layout.setContent(text != null ? text : "",
font.impl_getNativeFont());
layout.setWrapWidth((float) wrappingWidth);
return layout.getBounds().getWidth();
}
}
This Utility Class should work as posted. I removed some of the methods from the Class to meet this site character constraint. I got the Utility class from here.
This should solve your problem.
column.setCellFactory(col -> new TableCell<Object, String>()
{
#Override
protected void updateItem(final String item, final boolean empty)
{
super.updateItem(item, empty);
setText(item);
TableColumn tableCol = (TableColumn) col;
if (item != null && tableCol.getWidth() < new Text(item + " ").getLayoutBounds().getWidth())
{
tooltipProperty().bind(Bindings.when(Bindings.or(emptyProperty(), itemProperty().isNull())).then((Tooltip) null).otherwise(new Tooltip(item)));
} else
{
tooltipProperty().bind(Bindings.when(Bindings.or(emptyProperty(), itemProperty().isNull())).then((Tooltip) null).otherwise((Tooltip) null));
}
}
});
To create tooltip I use the following code based on this answer.
Callback<TableColumn,TableCell> existingCellFactory = column.getCellFactory();
column.setCellFactory(c -> {
TableCell cell = existingCellFactory.call((TableColumn) c);
Tooltip tooltip = new Tooltip();
tooltip.textProperty().bind(cell.textProperty());
cell.tooltipProperty().bind(
Bindings.when(Bindings.or(cell.emptyProperty(), cell.itemProperty().isNull()))
.then((Tooltip) null).otherwise(tooltip));
return cell ;
});
The problem is that in this case when user moves mouse on table on any cell tooltip appears there and user gets too many tooltips.
How to show tooltip only on those table cells which text is wider cell width and replaced to "..." at the end?
Here is my attempt at solving this.
Note: I am using com.sun.javafx.scene.control.skin.Utils based on this answer. Some methods appear to be depreciated. This answer assumes you are using the default font.
This app checks each table cell of a table and determine if the text inside the cell is ellipsized. It makes use of a JavaFx Utility.
Main
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;
/**
*
* #author Sedrick
*/
public class JavaFXApplication5 extends Application {
private final TableView<Person> table = new TableView<>();
private final ObservableList<Person> data =
FXCollections.observableArrayList(new Person("A", "B"), new Person("ZZZZZZZZZZZZZZZZ","XXXXXXXXXXXXXXXX"), new Person("ZZZ", "XXX"));
final HBox hb = new HBox();
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
Scene scene = new Scene(new Group());
stage.setWidth(450);
stage.setHeight(550);
TableColumn firstNameCol = new TableColumn("First Name");
firstNameCol.setMinWidth(100);
firstNameCol.setCellValueFactory(
new PropertyValueFactory<>("firstName"));
TableColumn lastNameCol = new TableColumn("Last Name");
lastNameCol.setMinWidth(100);
lastNameCol.setCellValueFactory(
new PropertyValueFactory<>("lastName"));
table.setItems(data);
table.getColumns().addAll(firstNameCol, lastNameCol);
final Button addButton = new Button("Add");
addButton.setOnAction((ActionEvent e) -> {
data.add(new Person("ZZZZZZZZZZZZZZZZ","XXXXXXXXXXXXXXXX"));
data.add(new Person("ZZZ", "XXX"));
});
hb.getChildren().addAll(addButton);
hb.setSpacing(3);
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(10, 0, 0, 10));
vbox.getChildren().addAll(table, hb);
((Group) scene.getRoot()).getChildren().addAll(vbox);
stage.setScene(scene);
stage.show();
//ScenicView.show(scene);
//loop through all the table cells
for(TableColumn tableColumn : table.getColumns())
{
for(int i = 0; i < table.getItems().size(); i++)
{
System.out.println(tableColumn.getCellData(i) + " isCellEllipsized: " + isCellEllipsized(tableColumn.getWidth(), tableColumn.getCellData(i).toString()));
}
}
}
boolean isCellEllipsized(double tableColumnWidth, String cellData)
{
Text text = new Text(cellData);//Convert String to Text
double textActualWidth = text.getBoundsInLocal().getWidth();//Get the width of the Text object
double textComputedWidth = Utility.computeTextWidth(text.getFont(), cellData, tableColumnWidth);//Use the utility. It returns how long the text should be if it needs to be ellipsized and the actual text lengh if it does not need to be ellipsized.
return textActualWidth > textComputedWidth;
}
public static class Person {
private final SimpleStringProperty firstName;
private final SimpleStringProperty lastName;
private Person(String fName, String lName) {
this.firstName = new SimpleStringProperty(fName);
this.lastName = new SimpleStringProperty(lName);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String fName) {
firstName.set(fName);
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String fName) {
lastName.set(fName);
}
}
}
Utility Class
/*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
import java.text.Bidi;
import java.text.BreakIterator;
import static javafx.scene.control.OverrunStyle.*;
import javafx.application.Platform;
import javafx.application.ConditionalFeature;
import javafx.geometry.Bounds;
import javafx.geometry.HPos;
import javafx.geometry.Point2D;
import javafx.geometry.VPos;
import javafx.scene.control.OverrunStyle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.scene.text.TextBoundsType;
import com.sun.javafx.scene.text.HitInfo;
import com.sun.javafx.scene.text.TextLayout;
import com.sun.javafx.tk.Toolkit;
/**
* BE REALLY CAREFUL WITH RESTORING OR RESETTING STATE OF helper NODE AS LEFTOVER
* STATE CAUSES REALLY ODD NASTY BUGS!
*
* We expect all methods to set the Font property of helper but other than that
* any properties set should be restored to defaults.
*/
public class Utility {
static final Text helper = new Text();
static final double DEFAULT_WRAPPING_WIDTH = helper.getWrappingWidth();
static final double DEFAULT_LINE_SPACING = helper.getLineSpacing();
static final String DEFAULT_TEXT = helper.getText();
static final TextBoundsType DEFAULT_BOUNDS_TYPE = helper
.getBoundsType();
/* Using TextLayout directly for simple text measurement.
* Instead of restoring the TextLayout attributes to default values
* (each renders the TextLayout unable to efficiently cache layout data).
* It always sets all the attributes pertinent to calculation being performed.
* Note that lineSpacing and boundsType are important when computing the height
* but irrelevant when computing the width.
*
* Note: This code assumes that TextBoundsType#VISUAL is never used by controls.
* */
static final TextLayout layout = Toolkit.getToolkit()
.getTextLayoutFactory().createLayout();
static double getAscent(Font font, TextBoundsType boundsType) {
layout.setContent("", font.impl_getNativeFont());
layout.setWrapWidth(0);
layout.setLineSpacing(0);
if (boundsType == TextBoundsType.LOGICAL_VERTICAL_CENTER) {
layout.setBoundsType(TextLayout.BOUNDS_CENTER);
} else {
layout.setBoundsType(0);
}
return -layout.getBounds().getMinY();
}
static double getLineHeight(Font font, TextBoundsType boundsType) {
layout.setContent("", font.impl_getNativeFont());
layout.setWrapWidth(0);
layout.setLineSpacing(0);
if (boundsType == TextBoundsType.LOGICAL_VERTICAL_CENTER) {
layout.setBoundsType(TextLayout.BOUNDS_CENTER);
} else {
layout.setBoundsType(0);
}
return layout.getBounds().getHeight();
}
static double computeTextWidth(Font font, String text,
double wrappingWidth) {
layout.setContent(text != null ? text : "",
font.impl_getNativeFont());
layout.setWrapWidth((float) wrappingWidth);
return layout.getBounds().getWidth();
}
}
This Utility Class should work as posted. I removed some of the methods from the Class to meet this site character constraint. I got the Utility class from here.
This should solve your problem.
column.setCellFactory(col -> new TableCell<Object, String>()
{
#Override
protected void updateItem(final String item, final boolean empty)
{
super.updateItem(item, empty);
setText(item);
TableColumn tableCol = (TableColumn) col;
if (item != null && tableCol.getWidth() < new Text(item + " ").getLayoutBounds().getWidth())
{
tooltipProperty().bind(Bindings.when(Bindings.or(emptyProperty(), itemProperty().isNull())).then((Tooltip) null).otherwise(new Tooltip(item)));
} else
{
tooltipProperty().bind(Bindings.when(Bindings.or(emptyProperty(), itemProperty().isNull())).then((Tooltip) null).otherwise((Tooltip) null));
}
}
});
well,I modified my code to eliminate other factors:
package com.shangzhu.drt;
import org.apache.poi.ss.usermodel.Picture;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
/**
* Created by lixiaoming on 2017/6/26.
*/
public class ImageTest2 {
private static void insertImageWithPOI() throws Exception {
XSSFWorkbook wwb = new XSSFWorkbook();
XSSFSheet ws = wwb.createSheet("sheet0");
BufferedImage image = ImageIO.read(new File("D:/poi.png"));
ByteArrayOutputStream baps = new ByteArrayOutputStream();
ImageIO.write(image,"png",baps);
int pictureIdx = wwb.addPicture(baps.toByteArray(), Workbook.PICTURE_TYPE_PNG);
XSSFDrawing drawing = ws.createDrawingPatriarch();
XSSFCreationHelper helper = wwb.getCreationHelper();
XSSFClientAnchor anchor = helper.createClientAnchor();
anchor.setCol1(1);
anchor.setRow1(1);
Picture picture = drawing.createPicture(anchor, pictureIdx);
picture.resize();
File excelFile = new File("D:/POI.xlsx");
OutputStream ops = new FileOutputStream(excelFile);
wwb.write(ops);
}
public static void main(String[] args) {
try {
insertImageWithPOI();
} catch (Exception e) {
e.printStackTrace();
}
}
}
below is the picture("D:/poi.png") in the code:
D:/poi.png
I don't think the source code which is dealing image has problems,But I don't know what I missed
I confirm that there is a problem when default column size is used. XSSFPicture.resize needs calculating the column widths in pixels to get the XSSFClientAnchor Col2 and the Dx2. As long as default column size is used, then this calculation seems to be wrong.
A workaround could be defining explicit column sizes before using XSSFPicture.resize. Then the calculation of the column widths in pixels seems to be correct.
In your code:
...
Picture picture = drawing.createPicture(anchor, pictureIdx);
for (int c=0; c<20; c++) ws.setColumnWidth(c, 11*256);
picture.resize();
...
Just like the image, I want to make 1 and 3 align same with 2. The table is default alignment.
What should I do?
Here is a simple way of doing it , add both to the same paragraph
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
public class ItextMain {
public static final String DEST = "simple_table4.pdf";
public static void main(String[] args) throws IOException, DocumentException {
File file = new File(DEST);
// file.getParentFile().mkdirs();
new ItextMain().createPdf(DEST);
}
public void createPdf(String dest) throws IOException, DocumentException {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
document.add(new Paragraph("1-Not aligned with table"));
document.add(new Chunk());
Paragraph p = new Paragraph();
p.setIndentationLeft(20);// (20);
PdfPTable table = new PdfPTable(4);
for (int aw = 0; aw < 16; aw++) {
table.addCell("hi");
}
table.setHorizontalAlignment(Element.ALIGN_LEFT);
p.add(table);
//document.add(table);
p.add("3- Aligned with table");
document.add(p);
document.close();
}
}
The iText 5 PdfPTable class has a width percentage attribute which holds the width percentage that the table will occupy in the page. By default this value is 80 and the resulting table is horizontally centered on the page, i.e. in particular it is indented.
To prevent this, simply set the percentage value to 100:
PdfPTable table = ...;
table.setWidthPercentage(100);
Alternatively set the horizontal alignment:
table.setHorizontalAlignment(Element.ALIGN_LEFT);
I am trying to generate pdf file using itext. I need to add an element(Paragraph) above footer in the last page. I don't know how to position the element in that position.
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.ExceptionConverter;
import com.lowagie.text.Image;
import com.lowagie.text.Phrase;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfPageEventHelper;
import com.lowagie.text.pdf.PdfWriter;
public class PdfHeaderDecorator extends PdfPageEventHelper
{
public PdfHeaderDecorator()
{
super();
}
public void onEndPage(PdfWriter writer, Document document)
{
PdfPTable tableF = new PdfPTable(3);
try
{
tableF.setWidths(new int[]
{ 24, 24, 2 });
tableF.setTotalWidth(527);
tableF.setLockedWidth(true);
tableF.getDefaultCell().setFixedHeight(9);
tableF.getDefaultCell().setBorder(Rectangle.BOTTOM);
tableF.addCell(new Phrase("SOME Text"));
tableF.getDefaultCell().setHorizontalAlignment(Element.ALIGN_RIGHT);
tableF.addCell(new Phrase(String.format("page %d ", writer.getPageNumber())));
PdfPCell cell = new PdfPCell(new Phrase("bla bla bla"));
cell.setBorder(Rectangle.BOTTOM);
tableF.addCell(cell);
tableF.writeSelectedRows(0, -1, 34, 30, writer.getDirectContent());
}
catch (DocumentException de)
{
throw new ExceptionConverter(de);
}
}
}
And add your header decorator to page event
pdfWriter.setPageEvent(new PdfHeaderDecorator());