Apache POI Excel: How to set color transparency in charts? - apache-poi

I'm struggling to solve how to set opacity/transparency/alpha of colors in charts using Apache POI. Using the XDDF classes, there seems to be no way to do this. The Documentation of XDDFColor has no way to set this value when creating this object. The only thing that I thought may have worked was accessing the underlying CTHslColor from the XDDFColor as follows.
XDDFColor xddfColor = XDDFColor.from(PresetColor.LIGHT_GREEN);
CTColor container = xddfColor.getColorContainer();
CTHslColor hslColor = container.addNewHslClr();
CTPositiveFixedPercentage p = hslColor.addNewAlpha();
p.setVal(50000);
XDDFChartData.Series series = data.getSeries(2);
XDDFSolidFillProperties fill = new XDDFSolidFillProperties(xddfColor);
XDDFLineProperties line = new XDDFLineProperties();
line.setFillProperties(fill);
XDDFShapeProperties properties = series.getShapeProperties();
if (properties == null) {
properties = new XDDFShapeProperties();
}
properties.setLineProperties(line);
series.setShapeProperties(properties);
series.setFillProperties(fill);
While the color is correctly set in the chart, the transparency does not work. Is there any way to be able to set the fill color transparency for an Area Chart using POI?

The constructor XDDFSolidFillProperties(XDDFColor) creates a CTSolidColorFillProperties having a CTPresetColor corresponding to the given XDDFColor if that XDDFColor is instanceof XDDFColorPreset. And after that you should set the alpha, instead of manipulating the XDDFColor before. Also you should set fill properties as well as line properties to the XDDFShapeProperties and those to the series then. So:
private static void solidFillSeries(XDDFChartData data, int index, PresetColor color, int alpha) {
XDDFSolidFillProperties fill = new XDDFSolidFillProperties(XDDFColor.from(color));
org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties ctSolidColorFillProperties =
(org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties)fill.getXmlObject();
org.openxmlformats.schemas.drawingml.x2006.main.CTPresetColor ctPresetColor = ctSolidColorFillProperties.getPrstClr();
org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveFixedPercentage ctPositiveFixedPercentage = ctPresetColor.addNewAlpha();
ctPositiveFixedPercentage.setVal(alpha);
XDDFChartData.Series series = data.getSeries(index);
XDDFShapeProperties properties = series.getShapeProperties();
if (properties == null) {
properties = new XDDFShapeProperties();
}
properties.setFillProperties(fill);
XDDFLineProperties line = new XDDFLineProperties();
line.setFillProperties(fill);
properties.setLineProperties(line);
series.setShapeProperties(properties);
}
Complete example:
import java.io.FileOutputStream;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xddf.usermodel.*;
import org.apache.poi.xddf.usermodel.chart.*;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFDrawing;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class CreateExcelXDDFAreaChart {
public static void main(String[] args) throws Exception {
try (XSSFWorkbook document = new XSSFWorkbook()) {
XSSFSheet sheet = document.createSheet("SurfaceChart");
// create the data
String[] categories = new String[] { "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9" };
Double[] values1 = new Double[] { 10d, 20d, 10d, 15d, 12d, 20d, 10d, 18d, 19d };
Double[] values2 = new Double[] { 20d, 10d, 15d, 20d, 11d, 17d, 18d, 20d, 10d };
Double[] values3 = new Double[] { 14.5d, 14d, 13.5d, 13d, 12.5d, 12d, 11.5d, 11d, 10.5d };
int r = 0;
for (String cat : categories) {
sheet.createRow(r).createCell(0).setCellValue(cat);
sheet.getRow(r).createCell(1).setCellValue(values1[r]);
sheet.getRow(r).createCell(2).setCellValue(values2[r]);
sheet.getRow(r).createCell(3).setCellValue(values3[r]);
r++;
}
// create the chart
XSSFDrawing drawing = sheet.createDrawingPatriarch();
XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 5, 0, 20, 30);
XDDFChart chart = drawing.createChart(anchor);
// create data sources
int numOfPoints = categories.length;
XDDFDataSource<String> categoriesData = XDDFDataSourcesFactory.fromStringCellRange(sheet, new CellRangeAddress(0, numOfPoints-1, 0, 0));
XDDFNumericalDataSource<Double> valuesData1 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(0, numOfPoints-1, 1, 1));
XDDFNumericalDataSource<Double> valuesData2 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(0, numOfPoints-1, 2, 2));
XDDFNumericalDataSource<Double> valuesData3 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(0, numOfPoints-1, 3, 3));
// area chart
XDDFCategoryAxis categoryAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
XDDFValueAxis valueAxis = chart.createValueAxis(AxisPosition.LEFT);
valueAxis.setCrosses(AxisCrosses.AUTO_ZERO);
XDDFChartData data = chart.createData(ChartTypes.AREA, categoryAxis, valueAxis);
XDDFChartData.Series series = data.addSeries(categoriesData, valuesData1);
series.setTitle("Series 1", null);
series = data.addSeries(categoriesData, valuesData2);
series.setTitle("Series 2", null);
series = data.addSeries(categoriesData, valuesData3);
series.setTitle("Series 3", null);
chart.plot(data);
// set legend
XDDFChartLegend legend = chart.getOrAddLegend();
legend.setPosition(LegendPosition.BOTTOM);
solidFillSeries(data, 0, PresetColor.RED, 50000);
solidFillSeries(data, 1, PresetColor.GREEN, 50000);
solidFillSeries(data, 2, PresetColor.BLUE, 50000);
// Write the output to a file
try (FileOutputStream fileOut = new FileOutputStream("./CreateExcelXDDFAreaChart.xlsx")) {
document.write(fileOut);
}
}
}
private static void solidFillSeries(XDDFChartData data, int index, PresetColor color, int alpha) {
XDDFSolidFillProperties fill = new XDDFSolidFillProperties(XDDFColor.from(color));
org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties ctSolidColorFillProperties =
(org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties)fill.getXmlObject();
org.openxmlformats.schemas.drawingml.x2006.main.CTPresetColor ctPresetColor = ctSolidColorFillProperties.getPrstClr();
org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveFixedPercentage ctPositiveFixedPercentage = ctPresetColor.addNewAlpha();
ctPositiveFixedPercentage.setVal(alpha);
XDDFChartData.Series series = data.getSeries(index);
XDDFShapeProperties properties = series.getShapeProperties();
if (properties == null) {
properties = new XDDFShapeProperties();
}
properties.setFillProperties(fill);
XDDFLineProperties line = new XDDFLineProperties();
line.setFillProperties(fill);
properties.setLineProperties(line);
series.setShapeProperties(properties);
}
}
Hint: The value of the CTPositiveFixedPercentagealpha is percentage in units of 1000th (thousandth) percent. So it is from 0 to 100000 and 50000 is 50%.

Related

Apache POI cell borders

Apache POI cell border
I'm trying to create a sheet using Apache POI as below, but could not able to get proper borders for each cell in my sheet. I have set the borders using cellStyle.setBorder_____() methods as below. Not sure where I am going wrong with this.
public Sheet createInstructionsSheet(Workbook workbook)
{
Sheet sheet = workbook.createSheet(Constants.INSTRUCTIONS_SHEET_NAME);
sheet.protectSheet("financials");
int rowNum = 3;
String headerCellColor = "F8CBAD";
byte[] headerCellColorByte = null;
try {
headerCellColorByte = Hex.decodeHex(headerCellColor);
} catch (DecoderException e) {
e.printStackTrace();
}
XSSFColor headerColor = new XSSFColor(headerCellColorByte, null);
String bufferCellColor = "808080";
byte[] bufferCellColorByte = null;
try {
bufferCellColorByte = Hex.decodeHex(bufferCellColor);
} catch (DecoderException e) {
e.printStackTrace();
}
XSSFColor bufferColor = new XSSFColor(bufferCellColorByte, null);
ArrayList<String> instructions = new ArrayList<>();
instructions.add("1. Instruction 1.");
instructions.add("2. Instruction 2");
instructions.add("3. Instruction 3");
instructions.add("4. Instruction 4.");
Font headerFont = workbook.createFont();
headerFont.setBold(true);
headerFont.setFontName("Arial");
headerFont.setFontHeightInPoints((short) 14);
headerFont.setUnderline(HSSFFont.U_SINGLE);
headerFont.setColor(IndexedColors.BLACK.getIndex());
Font instructionsCellFont = workbook.createFont();
instructionsCellFont.setBold(false);
instructionsCellFont.setFontName("Arial");
instructionsCellFont.setFontHeightInPoints((short) 9);
instructionsCellFont.setColor(IndexedColors.BLACK.getIndex());
XSSFCellStyle headerCellStyle = (XSSFCellStyle) workbook.createCellStyle();
headerCellStyle.setFont(headerFont);
headerCellStyle.setFillForegroundColor(headerColor);
headerCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
headerCellStyle.setAlignment(HorizontalAlignment.CENTER);
headerCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
headerCellStyle.setWrapText(true);
headerCellStyle.setBorderBottom(BorderStyle.THIN);
headerCellStyle.setBorderTop(BorderStyle.THIN);
headerCellStyle.setBorderRight(BorderStyle.THIN);
headerCellStyle.setBorderLeft(BorderStyle.THIN);
XSSFCellStyle bufferCellStyle = (XSSFCellStyle) workbook.createCellStyle();
bufferCellStyle.setFillForegroundColor(bufferColor);
bufferCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
bufferCellStyle.setBorderBottom(BorderStyle.THIN);
bufferCellStyle.setBorderTop(BorderStyle.THIN);
bufferCellStyle.setBorderRight(BorderStyle.THIN);
bufferCellStyle.setBorderLeft(BorderStyle.THIN);
CellStyle instructionsCellStyle = workbook.createCellStyle();
instructionsCellStyle.setFont(instructionsCellFont);
instructionsCellStyle.setVerticalAlignment(VerticalAlignment.BOTTOM);
instructionsCellStyle.setAlignment(HorizontalAlignment.LEFT);
instructionsCellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
instructionsCellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
instructionsCellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
instructionsCellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
Row headerRow = sheet.createRow(0);
Cell headerCell1 = headerRow.createCell((short) 0);
headerCell1.setCellStyle(headerCellStyle);
headerCell1.setCellValue("INSTRUCTIONS TO UPLOAD DATA");
CellRangeAddress instructionsHeaderCell = new CellRangeAddress(0, 1, 0, 19);
sheet.addMergedRegion(instructionsHeaderCell);
Row bufferRow = sheet.createRow(2);
Cell bufferCell = bufferRow.createCell((short) 0);
bufferCell.setCellStyle(bufferCellStyle);
CellRangeAddress bufferMergedCell = new CellRangeAddress(2, 2, 0, 19);
sheet.addMergedRegion(bufferMergedCell);
for(String instruct:instructions)
{
Row instructionRow = sheet.createRow(rowNum);
Cell instructionCell = instructionRow.createCell((short) 0);
instructionCell.setCellStyle(instructionsCellStyle);
instructionCell.setCellValue(instruct);
CellRangeAddress instructionsValueCell = new CellRangeAddress(rowNum, rowNum, 0, 19);
sheet.addMergedRegion(instructionsValueCell);
++rowNum;
}
return sheet;
}
Can someone please help?
I'm trying to create a sheet using Apache POI as below, but could not able to get proper borders for each cell in my sheet. I have set the borders using cellStyle.setBorder_____() methods as below. Not sure where I am going wrong with this.

How to edit an excel sheet and give background color to excel sheet cells using open xml?

I had a requirement of reading a excel sheet and change the color of some specific cells.
using (SpreadsheetDocument spreadSheet = SpreadsheetDocument.Open(docName, true))
{
WorksheetPart wbPart = spreadSheet.WorkbookPart.WorksheetParts.FirstOrDefault();
Row row1 = getRow(1, wbPart);
foreach (Cell c2 in row1.Elements<Cell>())
{
if (c2.CellReference.Value == "G1")
{
AddbackgroundFormat(spreadSheet, c2, "56BEFB");
}
}
}
//Getting the row using row index
static Row getRow(uint rowIndex, WorksheetPart worksheetPart)
{
Worksheet worksheet = worksheetPart.Worksheet;
SheetData sheetData = worksheet.GetFirstChild<SheetData>();
Row row;
if (sheetData.Elements<Row>().Where(r => r.RowIndex == rowIndex).Count() != 0)
{
row = sheetData.Elements<Row>().Where(r => r.RowIndex == rowIndex).First();
}
else
{
row = new Row() { RowIndex = rowIndex };
sheetData.Append(row);
}
return row;
}
//Adding styles two cells using the color passed
static void AddbackgroundFormat(SpreadsheetDocument document, Cell c, string colorCode)
{
Fills fs = AddFill(document.WorkbookPart.WorkbookStylesPart.Stylesheet.Fills, colorCode);
AddCellFormat(document.WorkbookPart.WorkbookStylesPart.Stylesheet.CellFormats, document.WorkbookPart.WorkbookStylesPart.Stylesheet.Fills);
c.StyleIndex = (UInt32)(document.WorkbookPart.WorkbookStylesPart.Stylesheet.CellFormats.Elements<CellFormat>().Count() - 1);
}
static Fills AddFill(Fills fills1, string colorCode)
{
Fill fill1 = new Fill();
PatternFill patternFill1 = new PatternFill() { PatternType = PatternValues.Solid };
ForegroundColor foregroundColor1 = new ForegroundColor() { Rgb = colorCode };
//BackgroundColor backgroundColor1 = new BackgroundColor() { Indexed = (UInt32Value)64U };
patternFill1.Append(foregroundColor1);
// patternFill1.Append(backgroundColor1);
fill1.Append(patternFill1);
fills1.Append(fill1);
return fills1;
}
static void AddCellFormat(CellFormats cf, Fills fs)
{
CellFormat cellFormat2 = new CellFormat() { NumberFormatId = 0, FontId = 0, FillId = (UInt32)(fs.Elements<Fill>().Count() - 1), BorderId = 0, FormatId = 0, ApplyFill = true };
cf.Append(cellFormat2);
}

Can't I use await animation on Device.StartTimer()?

I'm making app with Xamarin.forms pcl.
If I use UIRefreshControl with Scrollview on iOS and animation same time.
It crash!
Is this bug of UIRefreshControl?
I provide reproduce sample code here.
https://github.com/myallb/test_pulltorefresh.git
Sample code is very simple.
Is there any mistake??
Thanks.
public partial class testPage : ContentPage
{
public PullToRefreshLayout RefreshView = null;
AbsoluteLayout layout;
public testPage()
{
InitializeComponent();
layout = new AbsoluteLayout()
{
BackgroundColor = Color.Purple,
};
ScrollView scrollview = new ScrollView()
{
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
Content = layout
};
RefreshView = new PullToRefreshLayout
{
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
Content = scrollview,
RefreshColor = Color.Red,
RefreshCommand = new Command(RefreshStart)
};
RefreshView.IsPullToRefreshEnabled = true;
Content = RefreshView;
Device.StartTimer(new TimeSpan(0, 0, 1), ani);
}
bool ani()
{
Label z = new Label()
{
Text = "Z",
TextColor = Color.White,
FontAttributes = FontAttributes.Bold,
FontSize = new Random().Next(22, 35)
};
AbsoluteLayout.SetLayoutBounds(z, new Rectangle(0.67 + new Random().Next(0, 10) / 100.0, 0.13 + new Random().Next(0, 10) / 100.0, 40, 40));
AbsoluteLayout.SetLayoutFlags(z, AbsoluteLayoutFlags.PositionProportional);
layout.Children.Add(z);
Device.BeginInvokeOnMainThread(async () =>
{
Task t1 = z.FadeTo(0, 3500);
Task t2 = z.TranslateTo(0, -70, 3500, Easing.SinInOut);
await Task.WhenAll(t1, t2);
layout.Children.Remove(z);
});
return true;
}
void RefreshStart()
{
Debug.WriteLine("RefreshStart");
if (RefreshView != null)
RefreshView.IsRefreshing = true;
Device.BeginInvokeOnMainThread(async () =>
{
await Task.Delay(20);
Debug.WriteLine("RefreshEnd");
RefreshView.IsRefreshing = false;
});
}
}

The name 'InitializeComponent()' does not exist in the current context (c#, emgucv)

I am trying to run this code using c# and emgucv to draw a histogram for an image but it keeps giving me an error that 'The name 'InitializeComponent()' does not exist in the current context'. I tried to add references but it is not working.
using ZedGraph;
using System;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Runtime.InteropServices;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.UI;
using Emgu.Util;
using Emgu.CV.Structure;
using System.Windows.Forms;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Windows.Markup;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;
using System.Xaml;
using System.Xml;
;
namespace My_EMGU_Program
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog Openfile = new OpenFileDialog();
if (Openfile.ShowDialog() == DialogResult.OK)
{
Image<Bgr, byte> img = new Image<Bgr, byte>(Openfile.FileName);
float[] BlueHist;
float[] GreenHist;
float[] RedHist;
DenseHistogram Histo = new DenseHistogram(255, new RangeF(0, 255));
Image<Gray, Byte> img2Blue = img[0];
Image<Gray, Byte> img2Green = img[1];
Image<Gray, Byte> img2Red = img[2];
Histo.Calculate(new Image<Gray, Byte>[] { img2Blue }, true, null);
//The data is here
//Histo.MatND.ManagedArray
BlueHist = new float[256];
Histo.MatND.ManagedArray.CopyTo(BlueHist, 0);
Histo.Clear();
Histo.Calculate(new Image<Gray, Byte>[] { img2Green }, true, null);
GreenHist = new float[256];
Histo.MatND.ManagedArray.CopyTo(GreenHist, 0);
Histo.Clear();
Histo.Calculate(new Image<Gray, Byte>[] { img2Red }, true, null);
RedHist = new float[256];
Histo.MatND.ManagedArray.CopyTo(RedHist, 0);
float[] GrayHist;
Image<Gray, Byte> img_gray = new Image<Gray, byte> (Openfile.FileName);
Histo.Calculate(new Image<Gray, Byte>[] { img_gray }, true, null);
//The data is here
//Histo.MatND.ManagedArray
GrayHist = new float[256];
Histo.MatND.ManagedArray.CopyTo(GrayHist, 0);
/*This Methof call will produced the Histograms for you*/
Add_Histogram(GrayHist, "Gray Histogram");
Add_Histogram(BlueHist, "Blue Histogram");
Add_Histogram(GreenHist, "Green Histogram");
Add_Histogram(RedHist, "Red Histogram");
}
}
/* You can extend this method to set line colour x and y titles quite easily */
//Global X Y locations to stack Histograms
int X = 10, Y = 10;
Panel panel1 = new Panel();
void Add_Histogram(float[] Histo_dat, string Histo_Title = "Histogram Title")
{
//Create the Control
ZedGraphControl zgc = new ZedGraphControl();
zgc.Location = new Point(Y, X);
zgc.Size = new Size(panel1.Width - 20, 200);
X += (zgc.Size.Height + 20); //increas X for next Graph
GraphPane myPane = zgc.GraphPane;
myPane.Title.Text = Histo_Title;
myPane.XAxis.Title.Text = "X Axis - Pixel Bin Values";
myPane.YAxis.Title.Text = "Y Axis - Total Number of Pixels";
//Create an array that Zedgraph can use
PointPairList list1 = new PointPairList();
for (int i = 0; i < Histo_dat.Length; i++)
{
list1.Add(new PointPair(i, Histo_dat[i]));
}
//Add the data to the control
LineItem myCurve = myPane.AddCurve("Title", list1, Color.Blue, SymbolType.Circle);
zgc.AxisChange();
//Add the controll and refresh form
panel1.Controls.Add(zgc);
this.Refresh();
}
//In case you wish to restart and draw newly calculated histograms
void Clear_Histograms()
{
panel1.Controls.Clear();
X = 10;
}
}
}
Form1 is a partial class.
Which means there is another file Form1.designer.cs that contains the missing method.
You can't just copy and paste that code - you need the files that accompany it:
Form1.cs, Form1.designer.cs and maybe some resource files such as Form1.resx.
I suggest going through the basics before attempting complicated code.

Integer Columns in ScalaFX TableView

I am new to ScalaFX. I am trying to adapt a basic TableView example, to include Integer columns.
So far, I have come up with the following code:
class Person(firstName_ : String, age_ : Int) {
val name = new StringProperty(this, "Name", firstName_)
val age = new IntegerProperty(this, "Age", age_)
}
object model{
val dataSource = new ObservableBuffer[Person]()
dataSource += new Person("Moe", 45)
dataSource += new Person("Larry", 43)
dataSource += new Person("Curly", 41)
dataSource += new Person("Shemp", 39)
dataSource += new Person("Joe", 37)
}
object view{
val nameCol = new TableColumn[Person, String]{
text = "Name"
cellValueFactory = {_.value.name}
}
val ageCol = new TableColumn[Person, Int]{
text = "Age"
cellValueFactory = {_.value.age}
}
}
object TestTableView extends JFXApp {
stage = new PrimaryStage {
title = "ScalaFx Test"
width = 800; height = 500
scene = new Scene {
content = new TableView[Person](model.dataSource){
columns += view.nameCol
columns += view.ageCol
}
}
}
}
The problem is that, while the nameCol works well, the ageCol doesn't even compile.
In the line cellValueFactory = {_.value.age}, I get a type mismatch error. It is expecting a ObservableValue[Int,Int] but getting an IntegerProperty.
I am using ScalaFX 1.0 M2, compiled for Scala 2.10.
Change IntegerProperty to ScalaFX ObjectProperty[Int], simply:
val age = ObjectProperty(this, "Age", age_)
The rest can stay the same.
so try...
TableColumn<Person, String> firstNameCol = new TableColumn<>("First Name");
or table action
TableColumn<Person, Boolean> actionCol = new TableColumn<>("Action");
actionCol.setSortable(false);
actionCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Person, Boolean>, ObservableValue<Boolean>>() {
#Override public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<Person, Boolean> features) {
return new SimpleBooleanProperty(features.getValue() != null);
}
});

Resources