i am using the following code to set water mark in the excel sheet, i also get the water mark but instead of showing the watermark at the back round it shows the water mark at foreground.
how to resolve this, the code :
//to add water mark
HSSFPatriarch dp = sheet.createDrawingPatriarch();
HSSFClientAnchor anchor = new HSSFClientAnchor
(0, 0, 1023, 255, (short) 2, 4, (short) 13, 26);
HSSFTextbox txtbox = dp.createTextbox(anchor);
HSSFRichTextString rtxt = new HSSFRichTextString("POC");
HSSFFont draftFont = hwb.createFont();
draftFont.setColor((short) 27);
draftFont.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
draftFont.setFontHeightInPoints((short) 192);
draftFont.setFontName("Verdana");
rtxt.applyFont(draftFont);
txtbox.setString(rtxt);
txtbox.setLineStyle(HSSFShape.LINESTYLE_NONE);
txtbox.setNoFill(true);
also how to merge the cells to add title at the top of the excel sheet using poi in java?
Please help me to find and resolve the isssue.
Related
I'm new to itext7
Recently, I'm generating custom report pdf by iText7.
There is one layout I want to approach.
Make the vertically text align in the middle of the cell.
To illustrate my purpose, the first screenshot demonstrate my progress.
The second screenshot is what I want.
Here is how I implement my approach.
//Init table
Table table = new Table(UnitValue.createPercentArray(new float[]{20, 20, 20, 20, 20})).setWidth(UnitValue.createPercentValue(100));
//Init cellHeader
Paragraph servicePara = new Paragraph("Date of Service");
servicePara.setBorder(new SolidBorder(new DeviceRgb(5, 10, 50), 1));
servicePara.setBackgroundColor(DeviceCmyk.YELLOW);
servicePara.setRotationAngle(Math.PI / 2);
Cell cell = new Cell();
cell.add(servicePara);
table.addHeaderCell(cell);
I am trying to set border, margin, and padding to a PDF document, is it possible to achieve using itext7
Margin works fine by setting below code
document.setLeftMargin(180);
But the border is not working, below code used to set the border
float width = 1.5f;
Color color = ColorConstants.BLUE;
Border border = new DottedBorder(color,width);
Document document = new Document(pdfDocument);
document.setBorder(border);
Unfortunately it's not possible to specify the document's background and borders just by setting some of the Document's properties. The good news is that iText7 provides us with an opportunity to override DocumentRenderer (renderers are classes responsible to render corresponding model objects, for example, ParagraphRenderer renders Paragraph and so on).
In the custom DocumentRenderer below updateCurrentArea was overridden to tackle the following two issues:
shrinking the area which will be used by DocumentRenderer to layout the Document's children
adding a background Div, whic will be resposible for border rendering (I've also shown how one could set background, if needed)
class CustomDocumentRenderer extends DocumentRenderer {
public CustomDocumentRenderer(Document document) {
super(document);
}
#Override
protected LayoutArea updateCurrentArea(LayoutResult overflowResult) {
LayoutArea area = super.updateCurrentArea(overflowResult); // margins are applied on this level
Rectangle newBBox = area.getBBox().clone();
// apply border
float[] borderWidths = {10, 10, 10, 10};
newBBox.applyMargins(borderWidths[0], borderWidths[1], borderWidths[2], borderWidths[3], false);
// this div will be added as a background
Div div = new Div()
.setWidth(newBBox.getWidth())
.setHeight(newBBox.getHeight())
.setBorder(new SolidBorder(10))
.setBackgroundColor(ColorConstants.GREEN);
addChild(new DivRenderer(div));
// apply padding
float[] paddingWidths = {20, 20, 20, 20};
newBBox.applyMargins(paddingWidths[0], paddingWidths[1], paddingWidths[2], paddingWidths[3], false);
return (currentArea = new RootLayoutArea(area.getPageNumber(), newBBox));
}
}
The last quetions is how to apply it on your document. It could be done as follows:
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
doc.setRenderer(new CustomDocumentRenderer(doc));
The resultant PDF:
In the excel, here's what I expect, as shown below
enter image description here
In the excel, there is a data labels on the chart, the values displayed default to horizontal, I can set text direction to rotate all text 270 in the text options of format data labels. but, I don't know how to implement this in code with apache poi? Could anyone help?
Here is the code:
XSSFDrawing drawing = (XSSFDrawing)sheet.createDrawingPatriarch();
XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 4, 27, 5);
XSSFChart chart = drawing.createChart(anchor);
XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
bottomAxis.setTitle("Week");
XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
leftAxis.setTitle("Face Amount ($MM)");
leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN);
leftAxis.setMaximum(10000);
XDDFDataSource<Double> xs = XDDFDataSourcesFactory.fromNumericCellRange((XSSFSheet) sheet,
new CellRangeAddress(299, 299, 0, NUM_OF_COLUMNS - 1));
XDDFNumericalDataSource<Double> ys = XDDFDataSourcesFactory.fromNumericCellRange((XSSFSheet) sheet,
new CellRangeAddress(300, 300, 0, NUM_OF_COLUMNS - 1));
XDDFChartData data = chart.createData(ChartTypes.BAR, bottomAxis, leftAxis);
XDDFChartData.Series series1 = data.addSeries(xs, ys);
series1.setTitle("2x", null);
chart.plot(data);
XDDFBarChartData bar = (XDDFBarChartData) data;
bar.setBarDirection(BarDirection.COL);
bar.setGapWidth(3);
bar.setBarGrouping(BarGrouping.STACKED);
//set data labels
XSSFChart xssfChart = (XSSFChart) chart;
CTPlotArea plotArea = xssfChart.getCTChart().getPlotArea();
CTBoolean ctBool = CTBoolean.Factory.newInstance();
ctBool.setVal(true);
plotArea.getBarChartArray(0).getSerArray(0).addNewDLbls().setShowVal(ctBool);
plotArea.getBarChartArray(0).getSerArray(0).getDLbls().addNewShowLeaderLines();
plotArea.getBarChartArray(0).getSerArray(0).getDLbls().setShowLeaderLines(ctBool);
ctBool.setVal(false);
plotArea.getBarChartArray(0).getSerArray(0).getDLbls().setShowSerName(ctBool);
plotArea.getBarChartArray(0).getSerArray(0).getDLbls().setShowPercent(ctBool);
plotArea.getBarChartArray(0).getSerArray(0).getDLbls().setShowLegendKey(ctBool);
plotArea.getBarChartArray(0).getSerArray(0).getDLbls().setShowCatName(ctBool);
plotArea.getBarChartArray(0).getSerArray(0).getDLbls().setShowLeaderLines(ctBool);
plotArea.getBarChartArray(0).getSerArray(0).getDLbls().setShowBubbleSize(ctBool);
As your code shows, you are setting the data labels using the underlying low level beans of apache poi.
But how can one working with those? There is no documentation about org.openxmlformats.schemas.drawingml.x2006.chart.* classes public available. So we need downloading the sources of ooxml-schemas from maven for example. Then we can use javadoc to create a API documentation. Now we can look how to create and use the classes.
But also we need the meanings of the XML elements and attributes, the classes are creating. For this one could study the Office Open XML specifications. But my preferred method is to create a simple *.xlsx file having the needed settings using Excel's GUI. Then unzip that *.xlsx file and have a look at the XML in the *.xml files stored in that ZIP archive. For the first chart this is /xl/charts/chart1.xml.
Doing this we will find:
<c:dLbls>
<c:txPr>
<a:bodyPr rot="-5400000"/>
<a:p><a:pPr><a:defRPr/></a:pPr></a:p>
</c:txPr>
...
</c:dLbls>
for data labels when text rotation is set.
That is a txPr (text properties) element in dLbls having a bodyPr (body properties) element having a rot attribute set. Value of the rot attribute is rotation angle * 60000. The -5400000 for example is -90.00 * 60000. Also there is a p (paragraph) element having a pPr (paragraph properties) element having a defRPr (default run properties) to set that the data label text runs have default properties.
Putting all together the code used in apache poi for this would be:
...
// text properties having rotation set
plotArea.getBarChartArray(0).getSerArray(0).getDLbls().addNewTxPr()
.addNewBodyPr().setRot((int)(-90.00 * 60000));
// paragraph properties having default run properties set
plotArea.getBarChartArray(0).getSerArray(0).getDLbls().getTxPr()
.addNewP().addNewPPr().addNewDefRPr();
...
where plotArea is CTPlotArea as in your code. And the first series must have dLbls set using addNewDLbls as you done in your code.
I created a line chart and when I add the title to my chart it overlaps my data. How do I add the title above my chart? Also how can I adjust the font/style of the title text? I want to make the text a little smaller.
Drawing drawing = sheet.createDrawingPatriarch();
ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, 10, 15);
Chart chart = drawing.createChart(anchor);
chart.setTitleText("This is my title");
// Use a category axis for the bottom axis.
ChartAxis bottomAxis = chart.getChartAxisFactory().createCategoryAxis(AxisPosition.BOTTOM);
ValueAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT);
ChartDataSource<Integer> test = DataSources.fromArray([2011,2012,2013,2014,2015,2016,2017] as Integer[]);
ChartDataSource<Integer> test2 = DataSources.fromArray([4805, 7351, 5333, 7183, 6230, 4050, 6963] as Integer[]);
LineChartData data = chart.getChartDataFactory().createLineChartData();
data.addSeries(test, test2);
chart.plot(data, bottomAxis, leftAxis);
So from this example what I looking for is extra padding/margin above the 8000 where my title would go.
So you don't want the title overlaying the plot area?
The problem is that apache poi was tested using Excel 2007. But after this version multiple default settings have been changed in later versions.
The setting of overlays for example had defaulted to false (do not overlay) in Excel 2007 if it was not explicit set. This was a good choice in my opinion. In later versions the default is true (do overlay) if it is not explicit set. That's nonsense in my opinion. But who cares my opinion.
So if we not want the title overlaying the plot area, we have to set this explicitly.
Styling the title font is possible only using the low level underlying objects. Using this we need add run properties to the title's first paragraph and first text run. Then we can set bold, italic and font size (unit 1/100 pt). And then we add type face for latin and complex script characters.
Example code using Java. (The code in the question seems to be Groovy, but it is not tagged as such and there is no answer to my question about this discrepancy.)
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.charts.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.*;
public class LineChartProblem {
public static void main(String[] args) throws IOException {
try (XSSFWorkbook wb = new XSSFWorkbook()) {
Sheet sheet = wb.createSheet("linechart");
Drawing drawing = sheet.createDrawingPatriarch();
ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, 10, 15);
Chart chart = drawing.createChart(anchor);
((XSSFChart)chart).setTitleText("This is my title");
//set "the title overlays the plot area" to false explicitly
((XSSFChart)chart).getCTChart().getTitle().addNewOverlay().setVal(false);
//set font style for title - low level
//add run properties to title's first paragraph and first text run. Set bold.
((XSSFChart)chart).getCTChart().getTitle().getTx().getRich().getPArray(0).getRArray(0).addNewRPr().setB(true);
//set italic
((XSSFChart)chart).getCTChart().getTitle().getTx().getRich().getPArray(0).getRArray(0).getRPr().setI(true);
//set font size 20pt
((XSSFChart)chart).getCTChart().getTitle().getTx().getRich().getPArray(0).getRArray(0).getRPr().setSz(2000);
//add type face for latin and complex script characters
((XSSFChart)chart).getCTChart().getTitle().getTx().getRich().getPArray(0).getRArray(0).getRPr().addNewLatin().setTypeface("Times New Roman");
((XSSFChart)chart).getCTChart().getTitle().getTx().getRich().getPArray(0).getRArray(0).getRPr().addNewCs().setTypeface("Times New Roman");
// Use a category axis for the bottom axis.
ChartAxis bottomAxis = chart.getChartAxisFactory().createCategoryAxis(AxisPosition.BOTTOM);
ValueAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT);
ChartDataSource<Integer> test = DataSources.fromArray(new Integer[]{2011,2012,2013,2014,2015,2016,2017});
ChartDataSource<Integer> test2 = DataSources.fromArray(new Integer[]{4805, 7351, 5333, 7183, 6230, 4050, 6963});
LineChartData data = chart.getChartDataFactory().createLineChartData();
data.addSeries(test, test2);
chart.plot(data, bottomAxis, leftAxis);
// Write the output to a file
try (FileOutputStream fileOut = new FileOutputStream("ooxml-line-chart.xlsx")) {
wb.write(fileOut);
}
}
}
}
I want to populate some values in a sheet and then use jxl Formula to get the values from that sheet and write it to another sheet...
When I try to run this sample code
String filename = "C:\\input.xls";
WorkbookSettings ws = new WorkbookSettings();
ws.setLocale(new Locale("en", "EN"));
WritableWorkbook workbook =
Workbook.createWorkbook(new File(filename), ws);
WritableSheet s = workbook.createSheet("Input", 0);
WritableSheet s1 = workbook.createSheet("Output", 1);
s1.addCell(new Number(3, 0, 5));
s1.addCell(new Number(3, 1, 6));
s1.addCell(new Number(3, 2, 1));
s1.addCell(new Number(3, 3, 6));
s1.addCell(new Number(3, 4, 1));
Formula formula = new Formula(3,5,"AVERAGE(Output!D1:Output!D5)");
s.addCell(formula);
I am getting the last value in the AVG list has the output
=AVERAGE(Output!D5)
JAR Used : jxl 1.0.jar....
Solution tried :
1) Instead of giving it has a formula I gave it has label
Label label = new Label
(3,5,"AVERAGE(Output!D1:Output!D5)");
I got the entire text in the cell and gave '=' before the cell.. It worked like a charm. But I want this to be done with JXL API
2) Changed the JAR to jxl 2.6.jar
Now I am getting #VALUE! when I try to run the same. The cell content is
=AVERAGE(Output!D1:Output!D5) but still I get #VALUE!.
JAR Used : jxl 2.6.jar
This error is getting solved only when I go to that cell and press tab key or F2 key.
Please provide some solution
Regards
N.S.Balaji
It looks like excel is evaluating the formula in a strange way, hence why you are seeing #VALUE!. To see why the formula is failing, click on the formula cell and then go to Tools > Formula Auditing > Evaluate Formula. You will see that the steps are:
AVERAGE(Output!D1:Output!D5)
=AVERAGE(5:Output!D5)
=AVERAGE(5:1)
=AVERAGE(#VALUE!)
=#VALUE!
But when you execute F2+Enter on the cell, you will see that Excel changes its execution plan and gets the right answer.
I'm afraid the only thing I can think of to fix this is to use a comma-separated list, instead of a range:
Formula formula = new Formula(3,5, "AVERAGE(Output!D1,Output!D2,Output!D3,Output!D4,Output!D5)");
You can fix this problem if you put in e.g. Z1 = "=Output!D1", Z2 = "=Output!D2"...
and later you try AVERAGE(z1:z5) in your favorite cell