Liferay list export - liferay

I am displaying list of my custom objects on liferay portlet.
Now my problem is I want to provide Export feature to user.
There will be export link below list displayed.
When user click on that button it will download the displayed list as excel file.
I am generating excel file while generating the list for display.So, now my problem is how exactly export link should behave.
My export button code.
<portlet:actionURL name="exportURL" var="exportURL"></portlet:actionURL>
<p>← Export</p>
One approach I am thinking is after generating excel file I can upload it in Document library of Liferay and then provide download link as export link on portlet is it a good approch?

Instead of using <portlet:actionURL> you want to use <portlet:resourceURL>. This triggers the resource-phase of the portlet where you can serve other content types than just HTML snippets, e.g. Excel types.
I have the impression that you nailed the excel export itself already and just need an idea how to get to the export from the portlet UI, right? In serveResource you get a ResourceRequest and ResourceResponse object and can set the Mimetype for the response (and its OutputStream)

You should generate the file only after user clicks the link for export as adarshr has written in comment to your question. It will be useless waste of server resources if you generate the file and upload it to download center every time the list will show in the portlet.

You can use poi-2.5.1.jar for excel file generation in java.
Make use of serveResource method.
Below code snippet ,you can make use of.\
Workbook workBook = new HSSFWorkbook();
Sheet sheet = workBook.createSheet("new sheet");
Row row = sheet.createRow((short)0);
Cell cell = row.createCell(0);
//set row,cell value as per your custom entity
resourceResponse.setContentType("application/vnd.ms-excel");
OutputStream out = resourceResponse.getPortletOutputStream();
workBook.write(out);
HTH,
Regards

Related

Kentico 9 - Add content to an Editable Image Region (CMSEditableImage) programatically

We are looking for information on how to add content to an Editable Image programatically (with the Kentico C# API). Essentially, the equivalent of this Editable Region article for an Editable Image.
Any suggestions?
Thanks,
Victor
References:
CMSEditableImage Docs
Devnet Update EditableRegion Programatically
CMSEditableImage Class
You Sure Can
Each individual editable cms page control is stored in the document's DocumentContent field and can be accessed using an indexer field. For example:
TreeNode document = DocumentContext.CurrentDocument;
string editableImageControlId = "EditableImage1";
// get the field value
string editableImageContent = document.DocumentContent.EditableRegions[editableImageControlId];
// set it to something new
document.DocumentContent.EditableRegions[editableImageControlId] = newValue;
HOWEVER
If you look at the DocumentContent field in CMS_Document in the database you'll notice that all of the content is XML. That's because each control is serialized into XML and then nested inside this field. Thus, in this case, the value of the editableImageContent variable is an XML string:
<image>
<property name="imagepath">
~/Folder/ImageName.png
</property>
</image>
I wouldn't recommend trying to modify this directly since there's no telling if Kentico would ever change this code, or the individual control would ever change its serialization output.
But if you really must
You've got a couple of options:
1. Per #josh, you could create a new control that wraps the existing one and do some method override magic so that the control continues to do the serialization on your behalf and you just modify it after the fact. However this requires that the control is currently loading.
2. You could just hard code the beast and deal with it if it ever changes (which it likely will). Try:
// get the node from wherever you need to get the node
TreeNode document = DocumentHelper.GetDocuments().TopN(1).FirstObject;
var relativeMediaFilePath = "~/NewImage.png";
var xmlImage = string.Format("<image><property name=\"imagepath\">{0}</property></image>", relativeMediaFilePath);
var cmsControlId = "editableImage1";
if (document.DocumentContent.EditableRegions.ContainsKey(cmsControlId)) {
document.DocumentContent.EditableRegions[cmsControlId] = xmlImage;
}
else {
document.DocumentContent.EditableRegions.Add(cmsControlId, xmlImage);
}
// a little hack to get this field to be indicated as updated
document.SetValue("DocumentContent", document.DocumentContent.GetContentXml());
document.Update(true);
You could clone the editableimage webpart and then work in the prerender or change the override for the GetContent() method and add your own part of the string or do a string replace and add your code.
What is that you want to add to an Editable Image? - image path?! Not sure why you'd do that, but I'd take another direction: I'd add a field to a page type, which makes it much easier to work with through API. Having this field set up with API is should be quite easy to get it on the page... e.g. place editable image and use a macro to get field value.
Use
node.DocumentContent.EditableWebParts
and
node.DocumentContent.EditableRegions
collections to programmatically update editable content.
The best code example can be spotted at \CMS\CMSModules\Content\CMSDesk\Properties\Advanced\EditableContent\Main.aspx.cs
It's the dialog under Pages->General->Advanced->Edit regions & web parts.

Attachment download from view

Is there a way to list all documents in a view control (or a repeat control) and have a download button / link that will allow the user to download multiple attachments that reside in a rich text field?
I have found options using the #AttachmentName, however this lists all attachments on the document and does not restrict the attachments to just one the RTF.
I have a work around using a dialog box, which does work well, just not as clean as the option I was looking for.
In a view you can have a computed column. Any code you place into a dialog could be placed into a computed column. The getDocument() method of the XSPviewEntry gives you access to the document (recycle wisely).
update
To use a download control, use a repeat with the view as datasource and a panel per row. The panel has the data source pointing to a document. Use tr as tag for the panel.
This is only needed if you have attachments in other fields you don't want to show

Opening different xpages forms from a view panel

I have an Xpages application that pulls data from another .nsf file. I have a view panel linked to a view in that db. The view has documents with several different forms in it. I want to be able to open each document in it's own form(xpage).
How do I write a computed At Runtime, open selected document using: statement that will select the correct Xpage to present the document.
If you use the Data View component instead of a View Panel, you can compute the pageName attribute, referencing the var attribute to return a different value for each row based on the document that row represents. The flexibility of the Data View component also makes it easier to make your app look more like a modern web application and less like an Excel spreadsheet. As an additional bonus, the mobile theme invokes a renderer that makes each Data View instance look like a native mobile list, so using Data Views instead of View Panels simplifies mobile development.
You have 2 options:
use "use xpage associated with form" and edit the form's property
use a SSJS formula to compute the Form. You provide a variable name in the view control var to access a view row as XSPViewEntry. If the Form is in a view column even one you don't display you use .getColumnValue otherwise getDocument.getItemValueString
Does that work for you?
Maybe this mothed can help you: Unable to get document page name for
Hope this helps
Mark
I had a similar problem today. I use only one form but 3 different xpages for associated with this form. I have 3 different document types in the view. I used rowData the get the type of the document.
try{
var v=rowData.getColumnValue("form");
if(v.indexOf("x")> -1){var page ="x.xsp"}
else if(v.indexOf("y") > -1){var page = "y.xsp"}
else{var page = "z.xsp"}
}catch(e){
var page = "x.xsp"
}
So to your view you can create a column with the value of the form and you can use it.
I have used the extension library Dynamic View control which has an event you can code to get a handle to the NotesViewEntry which was selected. See the demo database page Domino_DynamicView.xsp and the Custom Event Handler tab for an example.
Note, in 8.5.3 (I have not upgraded yet) if you add or edit the eventHandler for onColumnClick it will be added to the XPages source as an xe:eventHandler. It needs to be an xp:eventHandler to work. The way to do it is to copy the code in the source from the exiting event and delete it. Recreate the event and update the code. Then go back into the source and change the tags within the eventHandler to xp:.

Xpages File Upload Control does nothing

Background: One xpage bound to document1. On this xpages is a tabbed table contain several tabs. Each tab contains an panel bound to other data sources incl document2. Document2 is created and made a child of document1. In each panel is a table to allow the user to create the new document, as well as two view controls. Everything works beautifully...until...
Problem: I was asked to add a way to upload an attachment to the child document. I first created an rich text field on the bound document called "ScannedInvoice". I then create a File Upload Control from the core controls and bound it to document2/ScannedInvoice. By rule, I only want a single attachment, otherwise I would consider the openNTF upload control.
I cannot figure out why nothing appears on the back end when I upload a file and create a new document. Everything else works, but there is no attachment in the ScannedInvoice field and also no $FILE fields attached to the document either.
Thanks in advance for any tips. I have searched quite a bit and have not found any answers. - Steve
<xp:fileUpload id="fileUpload1"
value="#{document2.ScannedInvoice}" useUploadname="false"
style="font-size:8pt" filename="scannedinvoice.jpg"
mimetype="image/jpeg">
</xp:fileUpload>
Note: The field ScannedInvoice on the Invoice form is rich text.
Code to save button: document2.save()
Document2 has scope=request and ignoreRequestParam=true. Both of these have to be set like this in order to work. parentID=# document1.getNoteID()
a file upload needs a full refresh of the page to be able to upload the file. Make sure that you are doing that.
======================================
Update Domino 9.0.1 supports partial refresh uploads

Get a SharePoint InfoPath form to load in the browser from a task

I've published an InfoPath form, through the administrator route, to a document library. I can click new form on the document library and have my custom form load up in the browser. When the filled form is saved back to the list it fires off a workflow. The workflow creates a task for another user to go into the form and complete the missing fields (if there are any.)
The key here is that the partially filled form saved to the library needs to be the very same form opened in the first task. The link field of the task is automatically filled with the url to the list item, which is the xml for the partially filled form. The link is identical to that when you mouse over the item back in the document library but when it's clicked from the task it try's to open the form inside InfoPath itself and not inside the browser. So that's one problem with the link field that SharePoint automatically populates when you create a task.
Ideally I would want to associate the partially filled form with the task itself. I've done this before in workflow with infopath forms by putting the FormURN inside workflow.xml and then specifying the TaskType on the task. However this will create up a new form based on the template. How can I get it to use the existing xml on the list item which the workflow which the task is actually running on.
Suggestions would be very much appriciated.
Change the url to go this url
{SITE_COLECTION_URL}/_layouts/FormServer.aspx?XmlLocation={FORM_URL}&DefaultItemOpen=1
use the tutorial on this page and have a field on the forms ItemMetadata.xml called url and set it in the code
taskProperties.ExtendedProperties["url"] = SERVERURL + "/_layouts/FormServer.aspx?XmlLocation=" + FORMURL + "&DefaultItemOpen=1";
This is not the most elegant solution but does work well. You will need to modify the form to act as an action listener.
Instead of creating tasks, send out emails containing a link to the InfoPath. When the user opens the form customize the top of form to look like a task form with a checkbox, when the form is updated fire the workflow to check if the check box is complete, if so move on the workflow on.

Resources