How to set font in excel using customized data exporter in Primefaces? - primefaces

I am using primefaces 6.1. I need to export my report list to excel format.For this i used primefaces data exporter.Dataexporter is giving me excel format. I have also set font in the excel. But the font is not completely working in my excel file.The set font appears in the table header only.
My Code is like this:
public void postProcessXLS(Object document) {
HSSFWorkbook wb = (HSSFWorkbook) document;
HSSFSheet sheet = wb.getSheetAt(0);
HSSFRow header = sheet.getRow(0);
HSSFCellStyle cellStyle = wb.createCellStyle();
cellStyle.setFillForegroundColor(HSSFColor.AQUA.index);
cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
HSSFFont fontHeader = (HSSFFont) wb.createFont();
cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
fontHeader.setFontName("Magnus Nepali");
cellStyle.setFont(fontHeader);
for(int i=0; i < header.getPhysicalNumberOfCells();i++) {
HSSFCell cell = header.getCell(i);
cell.setCellStyle(cellStyle);
}
}
My button code is :
<p:commandButton id="excel" ajax="false">
<p:dataExporter type="xls" target="tblReport" fileName="report" postProcessor="#{shareDividendMB.postProcessXLS}" />
</p:commandButton>
My excel format is like this:
Only excel sheet header has changed to font defined and the remaining data have Arial font.I tried other than my font and the result is same.

Finally i got the solution.My working code is like this:
public void postProcessXLS(Object document) {
HSSFWorkbook wb = (HSSFWorkbook) document;
HSSFSheet sheet = wb.getSheetAt(0);
HSSFCellStyle cellStyle = wb.createCellStyle();
cellStyle.setFillForegroundColor(HSSFColor.AQUA.index);
cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
HSSFFont fontHeader = (HSSFFont) wb.createFont();
cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
fontHeader.setFontName("Magnus Nepali");
cellStyle.setFont(fontHeader);
for (Row row : sheet) {
for (Cell cell : row) {
cell.setCellStyle(cellStyle);
}
}
}

Related

SSIS Script Task does not work on second iteration of ForEach Loop Container

This is my first post on Stack Overflow and it surely will not be the last one. I had a very rough week trying to fix a problem with my SSIS Script Task in SSDT for VS2015.
The problem is the following:
I have a ForEach Loop Container in the Control Flow. I map a variable USER::FileName. This Variable I do use to process an excel file (replace commas with dots) in a Script Task and afterwards save the processed file and convert it to a flat file in data flow task. So far so good. But on the second loop of the ForEach Loop Container the original excel file is not processed properly. The names are set correctly but the commas are not replaced. I don't know what to try anymore. Maybe someone has any suggestion?
Edit 2: This is how the Script Task Code looks like:
using Excel = Microsoft.Office.Interop.Excel;
[Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
public void Main()
{
Excel._Application oApp = new Excel.Application();
Excel.Workbook oWorkbook = oApp.Workbooks.Open(Dts.Variables["User::SourcePath"].Value.ToString() + "\\" + Dts.Variables["User::FileName"].Value.ToString() + ".xls");
Excel.Worksheet oWorksheet = oWorkbook.Worksheets[1];
try
{
ChangeValues(oWorksheet);
oWorkbook.SaveAs("C:\\TEMP\\" + Dts.Variables["User::FileName"].Value.ToString() + ".xls");
oWorkbook.Close();
oApp.Quit();
oWorksheet = null;
oWorkbook = null;
oApp = null;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
Dts.TaskResult = (int)ScriptResults.Success;
}
catch (Exception e)
{
Dts.Events.FireError(0, "Script task", e.Message + "\r" + e.StackTrace, String.Empty, 0);
}
}
private static void ChangeValues(Excel.Worksheet oWorksheet)
{
Excel.Range range = oWorksheet.UsedRange;
int colNo = range.Columns.Count;
int rowNo = range.Rows.Count;
// read the values into an array.
object[,] cells = range.Value;
for (int j = 1; j <= colNo; j++)
{
for (int i = 1; i <= rowNo; i++)
{
if (j > 3 && cells[i, j] != null)
{
cells[i, j] = cells[i, j].ToString().Replace(",", ".");
}
}
}
// set the values back into the range.
range.Value = cells;
return;
}
}
Ok, I know this Post is a bit old but I found a solution for the problem a few weeks later and wanted to share it realy quickly with you guys. To debug the code I had to install Windows 10 and VS2017 on a VM because the Visual Studio Tools for Application (VSTA) Debugger that runs Script Tasks in SSIS does not work on VS2015 and SSDT is not available for VS2017 on Windows 7. So I was able to debug the Script on Windows 10 in VS2017 and found out that my code didn't open the correct excel sheet. Hope it might help anyone else with problems debugging SSIS Script Tasks.

Read CSV first line using CsvBeanReader

I have a CSV file which has 3 columns and file does not have any header column but it has fixed pattern (like for first column, It will have url, Second and third column will have checksum). To process individual column values, I am using CSVBeanReader.
CSVBeanReader reads values from 2nd line with below code:
ICsvBeanReader beanReader = new CsvBeanReader(new FileReader(path),
CsvPreference.EXCEL_NORTH_EUROPE_PREFERENCE);
String[] header = beanReader.getHeader(true);
header = new String[] { "docURL", "shaCheckSum", null };
CellProcessor[] processors = new CellProcessor[3];
processors = getChecksumProcessors();
ValueObj docRecord;
while ((docRecord = beanReader.read(ValueObj.class, header, processors)) != null) {
docRecordList.add(docRecord);
}
private static CellProcessor[] getChecksumProcessors() {
return new CellProcessor[] { new NotNull(), new NotNull(), null };
}
How should I read first line of csv file using CSVBeanReader which contains data?
CSV file contains data from first line like below:
ftp://folder_struc/filename.pdf;checksum1;checksum2
Please let me know.
I guess you should omit the String[] header = beanReader.getHeader(true); line. Try just var header = new String[] {...}

Why do I get label displacement when I export a pie or line chart?

I have been trying to figure out why this happens for quite a while. My page have three kinds of charts: bar, line and pie models. The pie and line gets labels displacement when I export it and the bar its just fine.
I think it has something to do with jqplot css. But still, it is quite frustrating.
My pie chart is in a dialog...
xhtml code:
<p:dialog id="expanded-mission-distribution-dialog" resizable="false"
widgetVar="expanded-mission-distribution-dialog-var" modal="true"
dynamic="true">
<p:panel id="expanded-mission-distribution-panel"
styleClass="expanded-chart-panel ">
<p:chart id="expanded-mission-distribution-chart" type="pie"
styleClass="jqplot-target legend-spacing legend-size chart-dimension-3"
widgetVar="expanded-mission-distribution-chart-var"
model="#{fatigueDataSummaryAircraftAnalysisH.expandedMissionDistributionChart}" />
<p:commandButton id="mission-distribution-export-button"
type="button" icon="ui-circle-export" styleClass="ui-command-button"
title="Click to save the chart as image"
onclick="exportChart('expanded-mission-distribution-chart-var')" />
</p:panel>
</p:dialog>
The javascript that exports charts (I had to use a different approach compared to the one used in Primefaces' showcase, due compatibility purposes):
function b64toBlob(b64Data, contentType, sliceSize) {
contentType = contentType || '';
sliceSize = sliceSize || 512;
var byteCharacters = atob(b64Data);
var byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
var blob = new Blob(byteArrays, {type: contentType});
return blob;
}
function exportChart(chart) {
// Exportando o gráfico como uma imagem.
var image = PF(chart).exportAsImage();
var fileName = "image.png";
var src = image.getAttribute('src');
var type = 'image/png';
var b64Data = src.split(',')[1];
var blob = b64toBlob(b64Data, type);
var link = document.createElement("a");
if (link.download !== undefined) { // feature detection
// Browsers that support HTML5 download attribute
link.setAttribute("href", window.URL.createObjectURL(blob));
link.setAttribute("download", fileName);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
} else {
alert('Chart export only works in Chrome (v20+), Firefox (Gecko v13+), IE (v10+), Safari (v6+) and Opera (v12.10+).');
}
Image of chart in dialog:
Pie chart inside my dialog
Image of exported chart:
Exported pie chart
There is nothing similar over internet or whatsoever, what could be the reason of this issue?

Add HTML to pdfCell in iTextSharp

I wanted to render a HTML string in a page with header and footer. I tried by PdfPageEventHelper to add header/footer and then load the HTML. It does work. However the HTML loads in the page without margins. I tried adding margin to body element in HTML, which didn't work. Then I tried to add a table to body and then load the HTML inside the Table using HTMLWorker.ParseToList and cell.AddElement. It resulted in an empty table without the HTML elements.
pdfDoc.Open();
iTextSharp.text.html.simpleparser.HTMLWorker hw = new iTextSharp.text.html.simpleparser.HTMLWorker(pdfDoc);
StyleSheet styles = new StyleSheet();
// hw.Parse(new StringReader(invoiceHTML));
PdfPTable bodyTable = new PdfPTable(1);
PdfPCell bodyCell = new PdfPCell();
bodyTable.AddCell(bodyCell);
pdfDoc.Add(bodyTable);
var htmlarraylist = iTextSharp.text.html.simpleparser.HTMLWorker.ParseToList(new StringReader(invoiceHTML), styles);
for (int k = 0; k < htmlarraylist.Count; k++)
{
var ele = (IElement)htmlarraylist[k];
bodyCell.AddElement(ele);
}
pdfDoc.Close();
You are creating a table, creating a cell, adding the cell to the table and then adding that table to the document. At this point these objects are done and you should treat them as read-only variables (at best). However, after those steps is when you start adding actual content to the cell and that's why you aren't seeing anything. You need to move your adding the cell to the table and your table to the document after the loop:
var bodyTable = new PdfPTable(1);
var bodyCell = new PdfPCell();
var htmlarraylist = iTextSharp.text.html.simpleparser.HTMLWorker.ParseToList(new StringReader(invoiceHTML), styles);
for (int k = 0; k < htmlarraylist.Count; k++) {
var ele = (IElement)htmlarraylist[k];
bodyCell.AddElement(ele);
}
bodyTable.AddCell(bodyCell);
pdfDoc.Add(bodyTable);

Fill PDF template acrofield with HTML formatted text using iTextSharp

I am using iTextSharp to fill in a PDF template. The data I am using is kept in a database and is formatted HTML. My problem is that when I load the AcroField with this text I get it to do the line breaks, but no bold nor italics.
I have already attempted to use an HtmlWorker, but all the examples online show it being used to convert HTML to a PDF, but I am trying to set an AcroField in a PDF template.
After spending days looking through forums and iTextsharp source code I found a solution. Instead of fill the Acrofield with the HTML formatted text, I used a ColumnText. I parse the html text and load the IElements into a Paragraph. Then add the paragraph to the ColumnText. Then I overlaid the ColumnText on top of where the Acrofield should be, using the coordinates of the field.
public void AddHTMLToContent(String htmlText,PdfContentByte contentBtye,IList<AcroFields.FieldPosition> pos)
{
Paragraph par = new Paragraph();
ColumnText c1 = new ColumnText(contentBtye);
try
{
List<IElement> elements = HTMLWorker.ParseToList(new StringReader(htmlText),null);
foreach (IElement element in elements)
{
par.Add(element);
}
c1.AddElement(par);
c1.SetSimpleColumn(pos[0].position.Left, pos[0].position.Bottom, pos[0].position.Right, pos[0].position.Top);
c1.Go(); //very important!!!
}
catch (Exception ex)
{
throw;
}
}
Here is an example of a call to this function.
string htmlText ="<b>Hello</b><br /><i>World</i>";
IList<AcroFields.FieldPosition> pos = form.GetFieldPositions("Field1");
//Field1 is the name of the field in the PDF Template you are trying to fill/overlay
AddHTMLToContent(htmlText, stamp.GetOverContent(pos[0].page), pos);
//stamp is the PdfStamper in this example
One thing I did run into while doing this is the fact that my Acrofield did have a predefined font size. Since this functions set the ColumnText on top on the field, any font changes will have to be done in the function. Here is an example of changing the font size:
public void AddHTMLToContent(String htmlText,PdfContentByte contentBtye,IList<AcroFields.FieldPosition> pos)
{
Paragraph par = new Paragraph();
ColumnText c1 = new ColumnText(contentBtye);
try
{
List<IElement> elements = HTMLWorker.ParseToList(new StringReader(htmlText),null);
foreach (IElement element in elements)
{
foreach (Chunk chunk in element.Chunks)
{
chunk.Font.Size = 14;
}
}
par.Add(elements[0]);
c1.AddElement(par);
c1.SetSimpleColumn(pos[0].position.Left, pos[0].position.Bottom, pos[0].position.Right, pos[0].position.Top);
c1.Go();//very important!!!
}
catch (Exception ex)
{
throw;
}
}
So, I have had to tweak this code around a bit the past few months, and I found a better/less round about way to do this.
public void Final(string text,string fieldName,string filename)
{
iTextSharp.text.pdf.PdfReader reader = null;
iTextSharp.text.pdf.PdfStamper stamp = null;
reader = new PdfReader(file path to template);
stamp = new PdfStamper(reader, new FileStream(path to new file, FileMode.CreateNew));
AcroFields form = stamp.AcroFields;
//get the position of the field
IList<AcroFields.FieldPosition> pos = form.GetFieldPositions(fieldName);
//tell itextSharp to overlay this content
PdfContentByte contentBtye = stamp.GetOverContent(pos[0].page);
//create a new paragraph
Paragraph par = new Paragraph();
//parse html
List<IElement> elements = HTMLWorker.ParseToList(new StringReader(text), null);
for (int k = 0; k < elements.Count; k++)
{
par.Add((IElement)elements[k]);
}
//create a ColumnText to hold the paragraph and set position to the position of the field
ColumnText ct = new ColumnText(contentBtye);
ct.SetSimpleColumn(pos[0].position.Left, pos[0].position.Bottom, pos[0].position.Right, pos[0].position.Top);
ct.AddElement(par);
ct.Go();
stamp.Close();
reader.Close();
}