Dynamically creating a layout and saving it as PDF - java

I want to export data to a PDF. As a test I first want to print just a TextView. This is my code:
public static void exportPdf (Context ctx) {
// create a new document
PdfDocument document = new PdfDocument();
// crate a page description
PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(1240, 1754, 1).create();
// start a page
PdfDocument.Page page = document.startPage(pageInfo);
// draw something on the page
LinearLayout content = new LinearLayout(ctx);
int measureWidth = View.MeasureSpec.makeMeasureSpec(page.getCanvas().getWidth(), View.MeasureSpec.EXACTLY);
int measuredHeight = View.MeasureSpec.makeMeasureSpec(page.getCanvas().getHeight(), View.MeasureSpec.EXACTLY);
content.measure(measureWidth, measuredHeight);
content.layout(0, 0, page.getCanvas().getWidth(), page.getCanvas().getHeight());
TextView tv = new TextView(content.getContext());
tv.setText("Test");
content.addView(tv);
content.draw(page.getCanvas());
// finish the page
document.finishPage(page);
// write the document content
...
}
The result is an empty page. What am I doing wrong?
Edit: It is not my goal to write a text on the pdf's canvas. I want to display a Layout. The TextView is just provisory.

Related

How can I add background color and image at a fixed position in a pdf at the same time using iText in java?

I am new to itext library. I want to add both background colour and image at a fix position at each page in my pdf. I tried to make use the following code given by itext community for my work - https://kb.itextpdf.com/home/it7kb/faq/how-can-i-add-an-image-to-all-pages-of-my-pdf
public static class ImageEventHandler implements IEventHandler {
protected Image img;
public ImageEventHandler(Image img) {
this.img = img;
}
#Override
public void handleEvent(Event event) {
PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
PdfDocument pdfDoc = docEvent.getDocument();
PdfPage page = docEvent.getPage();
Rectangle area = page.getPageSize();
PdfCanvas aboveCanvas = new PdfCanvas(page.newContentStreamAfter(),
page.getResources(), pdfDoc)
.setStrokeColor(ColorConstants.BLACK)
.setFillColor(new DeviceRgb(240, 230, 140))
.rectangle(area)
.fillStroke()
.restoreState();
new Canvas(aboveCanvas, pdfDoc, area)
.add(img);
}
}
With this image is coming on each page with background colour but other contents like paragraph and cells are hidden. Please help me understand how to use this concept?

Updating ImageViews within a TilePane with JavaFX (Simple Reference Problem?)

Currently, I am trying to update the ImageViews within each Tile of a TilePane.
Variable at top of class available to all methods: ImageView imgArray[] = new ImageView[20];
Creating the original TilePane:
public TilePane createTilePane() {
TilePane tile = new TilePane();
tile.setPrefColumns(5);
for (int i = 0; i < 20; i++) {
tile.getChildren().add(this.createImageView("https://media.forgecdn.net/avatars/141/115/636539774401917932.jpeg", i));
} //for
return tile;
} //createTilePane()
public ImageView createImageView(String url, int x) {
Image image = new Image(url);
imgArray[x] = new ImageView();
imgArray[x].setImage(image);
imgArray[x].setFitWidth(100.0);
imgArray[x].setFitHeight(100.0);
imgArray[x].setImage(image);
return imgArray[x];
} //createImageView()
The problem is whenever I want to change an image within the tilepane I can't. For example I want to be able to do: this.createImageView("url", 2); to change a Tile within the TilePane.
I can do that with no errors, but the image is not changing.
Any ideas?
createImageView does not update the scene. It simply creates a new ImageView and updates the array containing the data. You need to update the scene, if you want to change the display. The best way of doing this in this scenario is modifying the image property of the ImageView.
Note that I've rewritten your code a bit to reuse the Image instance. createImageView has been renamed to setImage, since this seems like a better name for what it's doing to me:
public TilePane createTilePane() {
// reuse large object
Image image = new Image("https://media.forgecdn.net/avatars/141/115/636539774401917932.jpeg");
TilePane tile = new TilePane();
tile.setPrefColumns(5);
for (int i = 0; i < 20; i++) {
ImageView imageView = createImageView();
imageView.setImage(image);
imgArray[i] = imageView;
tile.getChildren().add(imageView);
} //for
return tile;
} //createTilePane()
private ImageView createImageView() {
ImageView image = new ImageView();
image.setFitWidth(100d);
image.setFitHeight(100d);
return image;
}
public void setImage(int index, String url) {
ImageView imageView = imgArray[index];
Image image = new Image(url);
// change image in ImageView that was added to the scene
imageView.setImage(image);
}

Poi slide formatting

I have created a PPT presentation with apache POI and I ould like to add Title for the PPT with the below code. But it throws compilation error as
The type of the expression must be an array type but it resolved to List
public static void main(String args[]) throws IOException{
//creating presentation
XMLSlideShow ppt = new XMLSlideShow();
//getting the slide master object
XSLFSlideMaster slideMaster = ppt.getSlideMasters()[0];
//get the desired slide layout
XSLFSlideLayout titleLayout = slideMaster.getLayout(SlideLayout.TITLE);
//creating a slide with title layout
XSLFSlide slide1 = ppt.createSlide(titleLayout);
//selecting the place holder in it
XSLFTextShape title1 = slide1.getPlaceholder(0);
The problem here is that ppt.getSlideMasters() returns List<XSLFSlideMaster> instead of XSLFSlideMaster[] as you're expecting.
So, for the problem you want to solve the following code should be OK:
import org.apache.poi.xslf.usermodel.*;
import java.io.FileOutputStream;
import java.io.IOException;
public class Slideshow {
public static void main(String[] args) throws IOException {
//creating presentation
try (FileOutputStream out = new FileOutputStream("example.ppt");
XMLSlideShow ppt = new XMLSlideShow();) {
//getting the slide master object
XSLFSlideMaster slideMaster = ppt.getSlideMasters().get(0);
//get the desired slide layout
XSLFSlideLayout titleLayout = slideMaster.getLayout(SlideLayout.TITLE);
//creating a slide with title layout
XSLFSlide slide1 = ppt.createSlide(titleLayout);
//selecting the place holder in it
XSLFTextShape title1 = slide1.getPlaceholder(0);
title1.setText("Text title");
ppt.write(out);
}
}
}
And the result will be:

Create 2nd Page in a PDF Document

I have written an android app to do inspections. It collects the data and then formats it and places it on a PDF document. I am having a problem creating a 2nd page of the PDF before I save it and email it. I have commented out "PAGE 2 OF PDF". This section of code up to the declaration of pdfName is where the problem is. I do not want to use anything like iText or Apose. Can anyone help???
public void createPDF(){
// Create a object of PdfDocument
PdfDocument document = new PdfDocument();
// content view is TableLayout of data
View content = findViewById(id.final_table_layout_for_pdf_page_1);
// create a page info with attributes as below
// page number, height and width
// i have used height and width to that of pdf content view
int pageNumber = 1;
PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(content.getWidth(),
content.getHeight() - 20, pageNumber).create();
// create a new page from the PageInfo
PdfDocument.Page page = document.startPage(pageInfo);
// repaint the user's text into the page
content.draw(page.getCanvas());
// do final processing of the page
document.finishPage(page);
/* PAGE 2 OF PDF
content = findViewById(id.final_table_layout_for_pdf_page_2);
// create a page info with attributes as below
// for 2nd page
// i have used height and width to that of pdf content view
pageNumber = 2;
pageInfo = new PdfDocument.PageInfo.Builder(content.getWidth(),
content.getHeight() - 20, pageNumber).create();
// create a new page from the PageInfo
page = document.startPage(pageInfo);
// repaint the user's text into the page
content.draw(page.getCanvas());
// do final processing of the page
document.finishPage(page);*/
// saving pdf document to root dir
String pdfName = "pdf_inspection_demo.pdf";
// all created files will be saved at path /sdcard/PDFDemo_AndroidSRC/
File outputFile = new File("/storage/emulated/0/", pdfName);
try {
outputFile.createNewFile();
OutputStream out = new FileOutputStream(outputFile);
document.writeTo(out);
document.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
errorString = e.getMessage();
}
}
private void generatePDF() {
PdfDocument pdfDocument = new PdfDocument();
criNewPag(1,"ان شاء الله ",pdfDocument);
criNewPag(2,"ان شاء الله ربي ",pdfDocument);
File file = new File(Environment.getExternalStorageDirectory(), "GFG.pdf");
try {
pdfDocument.writeTo(new FileOutputStream(file));
Toast.makeText(getApplicationContext(), "PDF file generated successfully.", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
pdfDocument.close();
}
private void criNewPag(int numpag,String text, PdfDocument pdfDocument ){
Paint paint = new Paint();
Paint title = new Paint();
PdfDocument.PageInfo mypageInfo = new PdfDocument.PageInfo.Builder(pagewidth, pageHeight, numpag).create();
PdfDocument.Page myPage = pdfDocument.startPage(mypageInfo);
Canvas canvas = myPage.getCanvas();
bmp = BitmapFactory.decodeResource(getResources(), R.drawable.gfgimage);
scaledbmp = Bitmap.createScaledBitmap(bmp, 140, 140, false);
canvas.drawBitmap(scaledbmp, 56, 40, paint);
title.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.NORMAL));
title.setTextSize(15);
title.setColor(ContextCompat.getColor(this, R.color.purple_200));
canvas.drawText("A portal for IT professionals.", 209, 100, title);
canvas.drawText("Geeks for Geeks", 209, 80, title);
title.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
title.setColor(ContextCompat.getColor(this, R.color.purple_200));
title.setTextSize(15);
title.setTextAlign(Paint.Align.CENTER);
canvas.drawText(text, 150, 240, title);
pdfDocument.finishPage(myPage);
}

Load SVG file in javafx 2.0

I'd like to display a svg image in javafx 2.0, but I don't find such a thing in the API. I guess it's because it's still in beta.
Until the final release, how can I load a svg ? Is there already a library which can handle that, or do I need to parse myself the file and then create the corresponding shapes ?
Thanks
Based on the answer of this question I found a working solution.
1. Include references to the Batik SVG Toolkit jars
2. Implement your own Transcoder
(based on this answer by Devon_C_Miller)
class MyTranscoder extends ImageTranscoder {
private BufferedImage image = null;
#Override
public BufferedImage createImage(int w, int h) {
image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
return image;
}
#Override
public void writeImage(BufferedImage img, TranscoderOutput out) {
}
public BufferedImage getImage() {
return image;
}
}
3. Get a BufferedImage from your svg
(based on hint in this answer by John Doppelmann)
String uri = "path_to_svg/some.svg";
MyTranscoder transcoder = new MyTranscoder();
TranscodingHints hints = new TranscodingHints();
hints.put(ImageTranscoder.KEY_WIDTH, 20f); //your image width
hints.put(ImageTranscoder.KEY_HEIGHT, 20f); //your image height
hints.put(ImageTranscoder.KEY_DOM_IMPLEMENTATION, SVGDOMImplementation.getDOMImplementation());
hints.put(ImageTranscoder.KEY_DOCUMENT_ELEMENT_NAMESPACE_URI, SVGConstants.SVG_NAMESPACE_URI);
hints.put(ImageTranscoder.KEY_DOCUMENT_ELEMENT, SVGConstants.SVG_SVG_TAG);
hints.put(ImageTranscoder.KEY_XML_PARSER_VALIDATING, false);
transcoder.setTranscodingHints(hints);
TranscoderInput input = new TranscoderInput(url.toExternalForm());
transcoder.transcode(input, null);
BufferedImage bufferedImage = transcoder.getImage();
4. Create an InputStream from BufferedImage
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
JPEGImageEncoder imageEncoder = JPEGCodec.createJPEGEncoder(outputStream);
imageEncoder.encode(bufferedImage);
byte[] bytes = outputStream.toByteArray();
InputStream inputStream = new ByteArrayInputStream(bytes);
5. Add the image to your ImageView
//javafx.scene.image.Image
Image image = new Image(inputStream);
//javafx.scene.image.ImageView
ImageView imageView = new ImageView();
imageView.setImage(image);
this.getChildren().add(imageView);
Hope this will help!
I used #pmoule's answer above, but had better luck replacing his steps 3-5 with this:
MyTranscoder imageTranscoder = new MyTranscoder();
imageTranscoder.addTranscodingHint(PNGTranscoder.KEY_WIDTH, (float) width);
imageTranscoder.addTranscodingHint(PNGTranscoder.KEY_HEIGHT, (float) height);
TranscoderInput input = new TranscoderInput(new FileReader(file));
imageTranscoder.transcode(input, null);
BufferedImage bimage = imageTranscoder.getImage();
WritableImage wimage = SwingFXUtils.toFXImage(bimage, null);
ImageView imageView = new ImageView(wimage);
<panel-vbox-whatever>.getChildren().clear();
<panel-vbox-whatever>.getChildren().add(imageView);
Simpler, and it just worked better for me.
Try http://forums.oracle.com/forums/thread.jspa?threadID=2264379&tstart=0
you do not need batik, you can try WebView like this:
WebView view = new WebView();
view.setMinSize(500, 400);
view.setPrefSize(500, 400);
final WebEngine eng = view.getEngine();
eng.load("http://127.0.0.1/demo1.svg");
Convert the SVG to FXML and then it becomes trivial. The conversion can be done with XSLT. You can get the stylesheet from here:
http://jayskills.com/blog/2012/06/03/svg-to-fxml-using-netbeans/
Then after conversion to FXML you can load it as a Node with the built-in FXMLLoader:
FXMLLoader.setDefaultClassLoader(this.getClass().getClassLoader());
URL location = KayakMain.class.getResource("path/to/my/resource.fxml");
Parent root = FXMLLoader.load(location);

Categories