How to print pdf file with wicket and javascript - java

my wicket apliaction created some pdf file. now I want to add button to print it somethink like this: http://javascript.about.com/library/blprint.htm how I can do it ?

it looks you mix two things together. Your example is a javascript. It is not a PDF, it is just printing your document. It is equal as browser menu File -> Print, but the event is invoked from a javascript that handles button action. You can use the same button as in that example and add #print CSS to your web page to make your document nicely printable.
Also there is another way. If you want to print a PDF document from your application and you generate the PDF from Java code, look the following example for Wicket 1.6:
add(new Link<Void>("myPdfLink") {
private static final long serialVersionUID = 1L;
#Override
public void onClick() {
byte[] data = ... // TODO your data
final ByteArrayInputStream stream = new ByteArrayInputStream(data);
IResourceStream resourceStream = new AbstractResourceStream() {
private static final long serialVersionUID = 1L;
#Override
public InputStream getInputStream() throws ResourceStreamNotFoundException {
return stream;
}
#Override
public void close() throws IOException {
stream.close();
}
#Override
public String getContentType() {
return "application/pdf";
}
};
getRequestCycle().scheduleRequestHandlerAfterCurrent(
new ResourceStreamRequestHandler(resourceStream)
.setFileName("my-pdf-to-download.pdf")
.setContentDisposition(ContentDisposition.ATTACHMENT)
.setCacheDuration(Duration.ONE_SECOND)
);
}
});

Related

iText find position of text in pdf

I am creating a utility that will add a multi-line text field just below the last line of text in an existing PDF document. This will be used for people who want to add comments to a report that is generated from another system.
I followed the examples from the iText book, and also looked at this SO question: Get the exact Stringposition in PDF
So now I've got a method that parses the last page of the document and a custom listener that finds the coordinates of the text I'm looking for.
Here is my code parsing method:
private void parsePdfPage2(String src, int pageNum) throws IOException {
PdfReader reader = new PdfReader(src);
RenderListener listener = new MyTextRenderListener();
PdfContentStreamProcessor processor = new PdfContentStreamProcessor(listener);
PdfDictionary pageDic = reader.getPageN(pageNum);
PdfDictionary resourcesDic = pageDic.getAsDict(PdfName.RESOURCES);
processor.processContent(ContentByteUtils.getContentBytesForPage(reader, pageNum), resourcesDic);
}
And here is the listener:
public class MyTextRenderListener implements RenderListener {
#Override
public void beginTextBlock() {}
#Override
public void endTextBlock() {}
#Override
public void renderImage(ImageRenderInfo renderInfo) {}
#Override
public void renderText(TextRenderInfo renderInfo) {
// Check if this is the text marker
String text = renderInfo.getText();
if (text.equalsIgnoreCase("Comments")) {
// Found it
LineSegment ls = renderInfo.getBaseline();
System.out.println("Found at X: " + ls.getBoundingRectange().getX() +
", Y: " + ls.getBoundingRectange().getY());
}
}
}
However, now I need to send the found LineSegment object (or the individual coordinates) back to the original parsing method. Of course I could write the values to disk and read it in the parsing method, but that seems horrible. I'm pretty sure there is a more elegant way to achieve this and would appreciate pointers.
This is an old question but still:
You could save the results of the listener into a private list (in the class).
After that what's left to add is a public method (getResults()) which returns the list.
Simply call getResults after the processContent call since the synchronous nature of the processContent method guarentees the list to be filled correctly.
The only problem with this solution is that listeners can't be reused.

Cannot access UI elements inside vaadin FileUpload FinishListener

I am trying to provide capability to upload file in my vaadin application
protected Upload questionImageUpload = new Upload("Upload question", questionReceiver);
questionImageUpload.addFinishedListener(new Upload.FinishedListener() {
#Override
public void uploadFinished(Upload.FinishedEvent event) {
boolean hasLock = VaadinSession.getCurrent().hasLock();
button.setEnabled(false);
}
});
But, in my FinishListener.uploadFinished(), if I modify some UI element (in above, I disable a button), the modification does not get applied.
I assumed that this method may be invoked in a non UI thread so I checked whether VaadinSession is available by putting a breakpoint in uploadFinished above. But, VaadinSession.getCurrent() didn't return null. Also hasLock is also true.
What could be the reason?
I am running this vaadin application on Google App Engine (still running locally inside IntelliJ IDEA). Could that be the reason behind this?
File upload is done as a POST request to the server, containing the file data. When the upload is complete, Upload.FinishedListeners are called at the end of that POST request. While all thread locals are set up correctly, this is not a UI update request (or UIDL request) and the response which is sent to the browser only contains a text that informs the browser that the upload finished. Any UI updates done will be queued until another request asks for them.
Because of this, you need to either use #Push, so that the UI changes are pushed immediately to the client through the push channel, or enable polling at the latest when starting the upload, so that the poll request will pick up the UI changes.
I actually accomplish what you want to do with a SuccedListener. I have a code which updates an embedded component with picture uploaded. You can look at the code and take a cue from it. It can also disable the button. You can correct it not optimised but it works
public class PicUploader extends Upload implements SucceededListener, Receiver {
private static final long serialVersionUID = 1L;
File file;
public String fileName;
final String LOCATION = "/home/###";
Embedded image = new Embedded();
TextField field;
public PicUploader(Embedded image, String caption) {
this.image = image;
this.addSucceededListener(this);
this.setReceiver(this);
this.setCaption(caption);
this.setIcon(FontAwesome.UPLOAD);;
}
public PicUploader(Embedded image, TextField field) {
this.image = image;
this.addSucceededListener(this);
this.setReceiver(this);
this.field = field;
this.setButtonCaption(""+FontAwesome.UPLOAD);
this.setIcon(FontAwesome.UPLOAD);;
}
#Override
public OutputStream receiveUpload(String filename, String mimeType) {
// TODO Auto-generated method stub
FileOutputStream stream = null;
try {
file = new File(LOCATION
+ "/Pictures/"
+ System.currentTimeMillis()
+ filename.substring(filename.length() - 4,
filename.length()));
fileName = file.getName();
System.out.println("This is the file name " + filename);
stream = new FileOutputStream(file);
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
return stream;
}
#Override
public void uploadSucceeded(SucceededEvent event) {
// TODO Auto-generated method stub
image.setSource(new FileResource(file));
image.setVisible(true);
image.setWidth("150");
image.setHeight("200");
// float ratio = image.getHeight()/image.getWidth();
// image.setWidth(""+image.getWidth());
// image.setHeight(""+image.getHeight());
// field.setValue(getFileName());
this.setEnabled(false);
}
public String getFileName() {
return fileName;
}
}

How to get images to display it in Wicket?

I am stuck with images. I need to upload an image and then display it on my page.
What I am doing now is uploading file like this:
private Picture picture; *// picture model*
private FileUploadField fileUpload;
public PictureUploader() {
Form<?> form = new Form<Void>("uploadForm") {
/**
*
*/
private static final long serialVersionUID = -694488846250739923L;
protected void onSubmit() {
FileUpload uploadedFile = fileUpload.getFileUpload();
File newFile = new File(uploadedFile.getClientFileName());
picture.setImage(newFile);
PageParameters pageParameter = new PageParameters();
pageParameter.put("file", picture.getImage());
setResponsePage(DataPage.class,pageParameter);
}
};
add(form);
form.setMultiPart(true);
form.add(setFileUpload(new FileUploadField("fileUpload")));
}
Then I submit it and go to DataPage ( I show only the constructor):
public DataPage(final PageParameters parameters) {
File file;
if (parameters.containsKey("file")) {
// WHAT TO DO HERE? SINCE GET() FROM PAGEPARAMETERS DOES NOT WORK FOR IT!
}
final Label result = new Label("result", ?????);
add(result);
}
Who knows how to make it, please, help me figure it out.

AbstractResource.ResourceResponse blocks user-interface while writing to OutputStream

I want to download a CSV file using Wicket, by implementing an AbstractResource. It looks something like this:
public class ExportCsvFileResource extends AbstractResource
{
#Override
protected AbstractResource.ResourceResponse newResourceResponse(IResource.Attributes attributes)
{
AbstractResource.ResourceResponse resourceResponse = new AbstractResource.ResourceResponse();
resourceResponse.setContentType("text/csv");
resourceResponse.setFileName("exported-contacts-file.csv");
resourceResponse.setTextEncoding("utf-8");
resourceResponse.setWriteCallback(new AbstractResource.WriteCallback()
{
#Override
public void writeData(IResource.Attributes attributes) throws IOException
{
OutputStream stream = attributes.getResponse().getOutputStream();
generateContentInBatches(stream);
}
});
return resourceResponse;
}
private void generateContentInBatches(OutputStream stream)
{
int numberOfChunks=//...
for (int i=0; i<numberOfChunks; i++)
{
byte[] contentChunk = retrieveContentFromBackend(i);
IOUtils.write(contentChunk, stream);
}
}
}
The problem is that, while the content is being generated with the retrieveContentFromBackend function (which is quite time consuming), the user interface is unresponsive. I click the buttons etc. but nothing happens, only after the file is done being generate can I use the interface again.
How do I avoid blocking the user interface while the file is being generated gradually?
Take a look at RequestMapperApplication and MapperDemoResourceReference from wicket-examples.
You can mount resource references:
mountResource("/print/${sheet}/${format}", new MapperDemoResourceReference());
To load such a resource without blocking the page, you'll have to render a link which triggers the resource directly:
add(new WebMarkupContainer("link")
{
#Override
protected void onComponentTag(ComponentTag tag)
{
super.onComponentTag(tag);
PageParameters parameters = new PageParameters();
parameters.add("sheet", "sheet1");
parameters.add("format", "A4");
tag.put("href", urlFor(new MapperDemoResourceReference(), parameters));
}
});
Here is an example of lazy loading:
http://www.wicket-library.com/wicket-examples/ajax/lazy-loading?1
I don't know how this works with your AbstractResource object but this should get you in the right direction.

Uploading Files through GWT-RPC?

Uploading files with GWT is usually done with a FileUpload inside a FormPanel like this:
// Create a FormPanel and point it at a service.
final FormPanel form = new FormPanel();
form.setAction("/myFormHandler");
// Because we're going to add a FileUpload widget, we'll need to set the
// form to use the POST method, and multipart MIME encoding.
form.setEncoding(FormPanel.ENCODING_MULTIPART);
form.setMethod(FormPanel.METHOD_POST);
// Create a panel to hold all of the form widgets.
VerticalPanel panel = new VerticalPanel();
form.setWidget(panel);
// Create a TextBox, giving it a name so that it will be submitted.
final TextBox tb = new TextBox();
tb.setName("textBoxFormElement");
panel.add(tb);
// Create a ListBox, giving it a name and some values to be associated with
// its options.
ListBox lb = new ListBox();
lb.setName("listBoxFormElement");
lb.addItem("foo", "fooValue");
lb.addItem("bar", "barValue");
lb.addItem("baz", "bazValue");
panel.add(lb);
// Create a FileUpload widget.
FileUpload upload = new FileUpload();
upload.setName("uploadFormElement");
panel.add(upload);
// Add a 'submit' button.
panel.add(new Button("Submit", new ClickHandler() {
public void onClick(ClickEvent event) {
form.submit();
}
}));
Are there any other ways to handle file upload with GWT? Is it possible to do in with GWT-RPC or REST?
Edit: Browser requirement is Only Webkit
With modern browsers you can get the raw bytes of the input type=file (in a base64 data url). Having the bytes you can send them whatever the way you like.
Here's some code, displaying a file input dialog and getting the raw bytes (dataURL):
class Util {
static native void info (Object obj) /*-{
if ($wnd.console && $wnd.console.log) $wnd.console.log (obj)
}-*/;
/** Fires a "click" event on an HTML element. */
public static native void click (final JavaScriptObject element) /*-{
if (element.click) element.click();
}-*/;
/** Read a file from the local filesystem. The file should have been choosen via an `input type=file`.
* See also: http://www.html5rocks.com/ru/tutorials/file/dndfiles/; http://www.w3.org/TR/FileAPI/ */
public static native void readFile (JavaScriptObject inputFile, V1<String> andThen) /*-{
var files = inputFile.files
if ($wnd.console) $wnd.console.log ('readFile; input: ', inputFile, files)
if (!files || !files.length) return
var reader = new FileReader()
reader.onload = function (progressEvent) {
//$wnd.console.log ('read event: ', progressEvent, 'read: ', reader.result)
andThen.#client.Closure.V1::call(Ljava/lang/Object;)(reader.result)
}
reader.readAsDataURL (files[0])
}-*/;
}
// Remove old form.
final Element oldForm = Document.get().getElementById ("uploadForm");
if (oldForm != null) oldForm.getParentNode().removeChild (oldForm);
// A hidden form used to upload the files.
final FormPanel form = new FormPanel();
form.getElement().setId ("uploadForm");
final Style formStyle = form.getElement().getStyle();
formStyle.setDisplay (Display.INLINE_BLOCK); formStyle.setOverflow (Overflow.HIDDEN); formStyle.setWidth (0, Unit.PX); formStyle.setHeight (0, Unit.PX);
form.setAction ("http://.../");
form.setEncoding (FormPanel.ENCODING_MULTIPART); form.setMethod (FormPanel.METHOD_POST);
final FileUpload upload = new FileUpload(); upload.setName ("image");
form.add (upload);
RootPanel.get().add (form);
upload.addChangeHandler (new ChangeHandler() {public void onChange (final ChangeEvent event) {
Util.info ("Loading: " + upload.getFilename());
Util.readFile (upload.getElement(), new V1<String>() {public void call (final String dataURL) {
Util.info ("Loaded: " + upload.getFilename() + " (url is " + dataURL.length() + " bytes)");
}});
}});
// Trigger the upload dialogue. See also: http://aspalliance.com/articleViewer.aspx?aId=1441&pId=-1
Util.click (upload.getElement());

Categories

Resources