I use the code that you can see below in order to strike through some cells in a jtable. Works great for me, and both in appearence and in print with JTable.print() method works excellent.
public void strikeThrough()
{
int rows=jTable.getRowCount();
destroiedDocs=new ArrayList<>();
for (int i = 0; i < rows; i++)
{
String test=String.valueOf(jTable.getValueAt(i,5));
if (test.equals("K"))
{
for (int j = 1; j < 5; j++)
{
String tostrike= String.valueOf(jTable.getValueAt(i, j));
String striked=("<html><strike>".concat(tostrike).concat("</strike> </html>"));
jTable.setValueAt(striked, i, j);
destroiedDocs.add(i);
}
}
}
}
The problem is that when I export the resaults to excel with the jxl class I got the value in these strike through cells with the appearence
<html><strike>some text</strike></html>
instead of some text in strikethrough.
Any recomandations on how to solve this formating problem?
I pass the cells in the excel cell by cell from the jtable with loops.
Thank you!
The JAVA code:
String striked=("<html><strike>".concat(tostrike).concat("</strike> </html>"));
jTable.setValueAt(striked, i, j);
Will work only for JAVA UI. After exporting data to excel it will show original text.
You need to perform following steps:
1. Before exporting remove <html><strike> and </strike></html>. Keep original text.
2. Use following code to strikethrough cell.
Run the following code using jxl-2.6.10.jar
import java.io.File;
import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableCell;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
public class ExcelCreate {
public static void main(String[] args) {
try {
WritableWorkbook workbook =
Workbook.createWorkbook(new File("output.xls"));
WritableSheet sheet = workbook.createSheet("Page1", 0);
String Label[] = new String[4];
Label[0] = "Emp ID";
Label[1] = "Name";
Label[2] = "Department";
Label[3] = "Designation";
WritableCellFormat cellFormat = new WritableCellFormat();
WritableFont font = new WritableFont(WritableFont.ARIAL);
font.setStruckout(true);
cellFormat.setFont(font);
for (int i = 0; i < Label.length; i++) {
Label label = new Label(i, 0, Label[i]);
sheet.addCell(label);
WritableCell cell = sheet.getWritableCell(i, 0);
cell.setCellFormat(cellFormat);
}
workbook.write();
workbook.close();
} catch (Exception e) {
/* Write your logic to handle exception.
*/
}
}
}
I think before export each cell to the Excel you'll have to find and replace or remove the tags like
<html>
and
<strike>
with appropriate functions to add the required formatting..
Which API are you using to export it to Excel Format??
I think it'll be Specific the one that you're using to export to Excel.
Related
I am using Apache POI to edit an existing file. This file contains multiple formulas that use the numbers that will be inputted through Apache. And this is where I run into problems, when a number is inputted and that cell is being used in a formula, the file gets corrupted and the formula disappears.
Here the formulas for the 0 are C7+D7, C8+D8, etc.
Here the formulas for the 0 became normal 0, the formulas got lost.
Here is the code I used to write to the excel file:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
public class write {
public static void main(String[] args) {
String excelFilePath = "C:\\Users\\jose_\\IdeaProjects\\writeExcel\\src\\JavaBooks.xlsx";
try {
FileInputStream inputStream = new FileInputStream(new File(excelFilePath));
Workbook workbook = WorkbookFactory.create(inputStream);
Sheet sheet = workbook.getSheetAt(0);
/*Cell cell2Update = sheet.getRow(1).getCell(3); // This updates a specific cell: row 0 cell 3
cell2Update.setCellValue(49);*/
Object[][] bookData = {
{2, 17},
{3, 27},
{4, 33},
{5, 44},
};
// int rowCount = sheet.getLastRowNum(); // Gets the last entry
int rowCount = 5;
for (Object[] aBook : bookData) {
Row row = sheet.createRow(++rowCount);
int columnCount = 1;
int lote = 1;
Cell cell = row.createCell(columnCount);
//cell.setCellValue(rowCount); // This sets the index for each entry
cell.setCellValue(lote);
for (Object field : aBook) {
cell = row.createCell(++columnCount);
if (field instanceof String) {
cell.setCellValue((String) field);
} else if (field instanceof Integer) {
cell.setCellValue((Integer) field);
}
}
}
inputStream.close();
FileOutputStream outputStream = new FileOutputStream("C:\\Users\\jose_\\IdeaProjects\\writeExcel\\src\\JavaBooks.xlsx");
workbook.write(outputStream);
workbook.close();
outputStream.close();
} catch (IOException | EncryptedDocumentException ex) {
ex.printStackTrace();
}
}
}
Is there a way to work around this or do I need to set all the formulas again through Apache POI?
You get the error because using code line Row row = sheet.createRow(++rowCount); you always create new empty rows and so you remove all cells in those rows. So you are also removing the cells containing the formulas. Doing so you are damaging the calculation chain. That's what the Excel GUI tells you with the messages.
You should not do this. Instead you always should try to get the rows first using Sheet.getRow. Only if that returns null then you need to create the row.
...
//Row row = sheet.createRow(++rowCount);
Row row = sheet.getRow(rowCount); if (row == null) row = sheet.createRow(rowCount); rowCount++;
...
Additional please read Recalculation of Formulas. So after changing cells referenced in formulas, do always either workbook.getCreationHelper().createFormulaEvaluator().evaluateAll(); or delegate re-calculation to Excel using workbook.setForceFormulaRecalculation(true);.
Java 8 and Apache POI 4.1.x here. I have some Java code that writes a list of objects to an Excel file and its working perfectly fine, with the exception of some color-based cell styles I'm trying to apply:
public void applyPriceListDataCellStyle(PriceListItem priceListItem, Cell cell) {
short colorIndex;
switch(priceListItem.getChangeType()) {
case ADDITION:
colorIndex = IndexedColors.YELLOW.getIndex();
break;
case DELETION:
XSSFColor purple = new XSSFColor(new java.awt.Color(120,81,169), new DefaultIndexedColorMap());
colorIndex = purple.getIndex();
break;
case PRICE_ADJUSTMENT_INCREASE:
colorIndex = IndexedColors.RED.getIndex();
break;
case PRICE_ADJUSTMENT_DECREASE:
colorIndex = IndexedColors.GREEN.getIndex();
break;
default:
// NO_CHANGE (leave unstyled)
colorIndex = IndexedColors.WHITE.getIndex();
break;
}
Map<String,Object> cellProps = new HashMap<>();
cellProps.put(CellUtil.FILL_FOREGROUND_COLOR, colorIndex);
cellProps.put(CellUtil.FILL_PATTERN, FillPatternType.SOLID_FOREGROUND);
CellUtil.setCellStyleProperties(cell, cellProps);
}
Above, the applyPriceListDataCellStyle method is called after a Cell is created from a Row object. The cell instance is then passed into this method as an argument, along with my PriceListItem bean (which is the data I'm writing to each row in the Excel file).
The PriceListItem bean has a ChangeType property (enum) that dictates what color the cell should appear as in the final Excel file.
At runtime, I am calling this method on the cells of 5 different rows (so 5 different PriceListItems) of each ChangeType value, and I get output that looks like:
So:
The 1st row, which is a "NO_CHANGE" (which maps to IndexedColors.WHITE) works perfectly fine, as expected
The 2nd row, which is an "ADDITION" (which maps to IndexedColors.YELLOW) works perfectly fine, as expected
The 3rd row, which is a "DELETION" (which maps to my custom purple color) appears jet black instead -- wrong!
The 4th row, which is a "PRICE_ADJUSTMENT_INCREASE" (which maps to IndexedColors.RED) appears gray -- wrong!
The 5th row, which is a "PRICE_ADJUSTMENT_DECREASE" (which maps to IndexedColors.GREEN) appears a lighter shade of gray -- wrong!
Where am I going awry on setting the colors on the cells of these various rows?
The apache poi CellUtil only works using org.apache.poi.ss.*. It cannot work using a XSSFColor because org.apache.poi.ss.usermodel.CellStyle has no method to get/set fill foreground color from a XSSFColor. It only works using short color indexes from IndexedColors. Hence the black color, because in your code purple.getIndex() always returns 0. So if CellUtil shall be used, which is to recommend, then choose a color from IndexedColors instead of creating a custom color. There is IndexedColors.VIOLET for example.
But the other wrong cases are not reproducible for me. The following Minimal, Reproducible Example works for me as expected. It needs a price-list-template.xlsx having at least one worksheet.
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellUtil;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class PoiColors {
public static void main(String[] args) throws IOException {
List<PriceListItem> priceList = new ArrayList<>();
PriceListItem noChange = new PriceListItem();
noChange.modelNumber = "123";
noChange.price = BigDecimal.valueOf(1.99);
noChange.changeType = ChangeType.NO_CHANGE;
PriceListItem addition = new PriceListItem();
addition.modelNumber = "456";
addition.price = BigDecimal.valueOf(2.99);
addition.changeType = ChangeType.ADDITION;
PriceListItem deletion = new PriceListItem();
deletion.modelNumber = "789";
deletion.price = BigDecimal.valueOf(3.99);
deletion.changeType = ChangeType.DELETION;
PriceListItem increase = new PriceListItem();
increase.modelNumber = "234";
increase.price = BigDecimal.valueOf(4.99);
increase.changeType = ChangeType.PRICE_ADJUSTMENT_INCREASE;
PriceListItem decrease = new PriceListItem();
decrease.modelNumber = "345";
decrease.price = BigDecimal.valueOf(5.99);
decrease.changeType = ChangeType.PRICE_ADJUSTMENT_DECREASE;
priceList.add(noChange);
priceList.add(addition);
priceList.add(deletion);
priceList.add(increase);
priceList.add(decrease);
new PoiColors().exportPriceList(priceList, "acme.xlsx");
}
private void exportPriceList(
List<PriceListItem> priceList,
String targetAbsPath) throws IOException {
// set variables based on specified format
String templateName = "price-list-template.xlsx";
// load the template
InputStream inp = this.getClass().getClassLoader().getResource(templateName).openStream();
Workbook workbook = WorkbookFactory.create(inp);
Sheet sheet = workbook.getSheetAt(0);
workbook.setSheetName(workbook.getSheetIndex(sheet), "ACME");
// plug in the header/metadata info and format some headers so they get autosized properly
Row row2 = CellUtil.getRow(1, sheet);
Cell c2 = CellUtil.getCell(row2, 2);
c2.setCellValue("ACME");
// create the data rows and apply styling
// start at row #11 which is where data rows begin
int rowNum = 11;
// rip through the items and write them to the rows; apply styling as appropriate
for (PriceListItem priceListItem : priceList) {
Row nextRow = sheet.createRow(rowNum);
Cell changeType = nextRow.createCell(0);
changeType.setCellValue(priceListItem.changeType.name());
applyPriceListDataCellStyle(priceListItem, changeType);
Cell modelNumber = nextRow.createCell(1);
modelNumber.setCellValue(priceListItem.modelNumber);
applyPriceListDataCellStyle(priceListItem, modelNumber);
Cell price = nextRow.createCell(2);
price.setCellValue(priceListItem.price.doubleValue());
applyPriceListDataCellStyle(priceListItem, price);
rowNum++;
}
// resize the columns appropriately
for (int c = 0; c < 3; c++) {
sheet.autoSizeColumn(c);
}
// export to file system
FileOutputStream fos = new FileOutputStream(targetAbsPath);
workbook.write(fos);
fos.close();
inp.close();
workbook.close();
}
private void applyPriceListDataCellStyle(PriceListItem priceListItem, Cell cell) {
short colorIndex;
switch(priceListItem.changeType) {
case ADDITION:
colorIndex = IndexedColors.YELLOW.getIndex();
break;
case DELETION:
colorIndex = IndexedColors.VIOLET.getIndex();
break;
case PRICE_ADJUSTMENT_INCREASE:
colorIndex = IndexedColors.RED.getIndex();
break;
case PRICE_ADJUSTMENT_DECREASE:
colorIndex = IndexedColors.GREEN.getIndex();
break;
default:
// NO_CHANGE (leave unstyled)
colorIndex = IndexedColors.WHITE.getIndex();
break;
}
Map<String,Object> cellProps = new HashMap<>();
cellProps.put(CellUtil.FILL_FOREGROUND_COLOR, colorIndex);
cellProps.put(CellUtil.FILL_PATTERN, FillPatternType.SOLID_FOREGROUND);
CellUtil.setCellStyleProperties(cell, cellProps);
}
}
class PriceListItem {
public String modelNumber;
public BigDecimal price;
public ChangeType changeType;
}
enum ChangeType {
NO_CHANGE,
ADDITION,
DELETION,
PRICE_ADJUSTMENT_INCREASE,
PRICE_ADJUSTMENT_DECREASE
}
Result is acme.xlsx which looks like so:
Using IndexedColors the colors are set in Office Open XML /xl/styles.xml as follows:
...
<fill>
<patternFill patternType="solid">
<fgColor indexed="13"/>
<bgColor indexed="64"/>
</patternFill>
</fill>
...
The indexed colors are not given by RGB but are taken from the default color palette. If you have the suspicion that your spreadsheet calculation application uses a different default color palette than Excel, then you can test this using the following code:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellUtil;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
public class TestIndexedColors {
public static void main(String[] args) throws Exception {
String templateName = "price-list-template.xlsx";
InputStream inp = TestIndexedColors.class.getClassLoader().getResource(templateName).openStream();
Workbook workbook = WorkbookFactory.create(inp);
Sheet sheet = workbook.getSheetAt(0);
Row row; Cell cell; int r = 11;
Map<String,Object> cellProps;
for (IndexedColors color : IndexedColors.values()) {
row = sheet.createRow(r++);
cell = row.createCell(0); cell.setCellValue(color.getIndex());
cell = row.createCell(1); cell.setCellValue(color.name());
cell = row.createCell(2);
cellProps = new HashMap<>();
cellProps.put(CellUtil.FILL_FOREGROUND_COLOR, color.getIndex());
cellProps.put(CellUtil.FILL_PATTERN, FillPatternType.SOLID_FOREGROUND);
CellUtil.setCellStyleProperties(cell, cellProps);
}
FileOutputStream out = new FileOutputStream("acme.xlsx");
workbook.write(out);
out.close();
workbook.close();
}
}
It needs a price-list-template.xlsx having at least one worksheet. The result acme.xlsx shows indexes, names and colors of all possible indexed colors using the current default color palette.
I am trying to create an Excel sheet that contains an Excel table using Java with the Apache POI library but I couldn't get a result file that is readable by Microsoft Excel 2016 (Office 365). This is my code:
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
class Scratch {
public static void main(String[] args) throws IOException {
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet("Table Sheet");
XSSFRow row0 = sheet.createRow(0);
row0.createCell(0).setCellValue("#");
row0.createCell(1).setCellValue("Name");
XSSFRow row1 = sheet.createRow(1);
row1.createCell(0).setCellValue("1");
row1.createCell(1).setCellValue("Foo");
XSSFRow row2 = sheet.createRow(2);
row2.createCell(0).setCellValue("2");
row2.createCell(1).setCellValue("Bar");
AreaReference area = workbook.getCreationHelper().createAreaReference(
new CellReference(row0.getCell(0)),
new CellReference(row2.getCell(1))
);
sheet.createTable(area);
try(FileOutputStream file = new FileOutputStream(new File("workbook.xlsx"))) {
workbook.write(file);
}
}
}
The code runs fine but when I open the output file in Excel I get a message that the file has unreadable content.
I have tried running the official sample and the result is the same. The official sample can be found here: https://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreateTable.java
I need to know the minimum code required to get a readable table.
I am using version 4.0.0 of Apache POI with Oracle JavaSE JDK 1.8.0_172 on Windows 10.
Not sure what happens with the "official sample" codes always. They seems not even be tested.
The CreateTable uses XSSFTable table = sheet.createTable(reference); which creates a table having 3 columns as given from the area reference. But all of those have id 1, so we need repairing. And of course the columns should not be created again then.
So repaired sample code would be:
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFTable;
import org.apache.poi.xssf.usermodel.XSSFTableStyleInfo;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
/**
* Demonstrates how to create a simple table using Apache POI.
*/
public class CreateTable {
public static void main(String[] args) throws IOException {
try (Workbook wb = new XSSFWorkbook()) {
XSSFSheet sheet = (XSSFSheet) wb.createSheet();
// Set which area the table should be placed in
AreaReference reference = wb.getCreationHelper().createAreaReference(
new CellReference(0, 0), new CellReference(2, 2));
// Create
XSSFTable table = sheet.createTable(reference); //creates a table having 3 columns as of area reference
// but all of those have id 1, so we need repairing
table.getCTTable().getTableColumns().getTableColumnArray(1).setId(2);
table.getCTTable().getTableColumns().getTableColumnArray(2).setId(3);
table.setName("Test");
table.setDisplayName("Test_Table");
// For now, create the initial style in a low-level way
table.getCTTable().addNewTableStyleInfo();
table.getCTTable().getTableStyleInfo().setName("TableStyleMedium2");
// Style the table
XSSFTableStyleInfo style = (XSSFTableStyleInfo) table.getStyle();
style.setName("TableStyleMedium2");
style.setShowColumnStripes(false);
style.setShowRowStripes(true);
style.setFirstColumn(false);
style.setLastColumn(false);
style.setShowRowStripes(true);
style.setShowColumnStripes(true);
// Set the values for the table
XSSFRow row;
XSSFCell cell;
for (int i = 0; i < 3; i++) {
// Create row
row = sheet.createRow(i);
for (int j = 0; j < 3; j++) {
// Create cell
cell = row.createCell(j);
if (i == 0) {
cell.setCellValue("Column" + (j + 1));
} else {
cell.setCellValue((i + 1.0) * (j + 1.0));
}
}
}
// Save
try (FileOutputStream fileOut = new FileOutputStream("ooxml-table.xlsx")) {
wb.write(fileOut);
}
}
}
}
Btw.: My code from How to insert a table in ms excel using apache java poi works as well using apache poi 4.0.0. The sheet.createTable() is deprecated. So do using XSSFTable table = sheet.createTable(null); instead. Because the area as well as all other things is set using low level classes. Not even more code than the new example though.
I am using apache poi 3.17 to create an Excel file.
Different columns may contain different type of values and I would like to style them accordingly. Rather than creating the style every time, I try to use the same style( to avoid the unnecessary object creation) and change the necessary properties. For eg: some cell I want to make italics, some bold, some with yellow color, some with underline etc..
But to my surprise, I found that style is not changing.
Below is a sample code where I try to set row 1 with 'yellow color' and rest with 'red color' but in the generated excel all rows are red.
import org.apache.poi.common.usermodel.HyperlinkType;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Hyperlink;
import org.apache.poi.xssf.usermodel.*;
import java.awt.*;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class WriteExcelBasic {
public static void main(String[] args) throws IOException {
String excelFileName = "/Users/username/Test3.xlsx";
FileOutputStream fos = new FileOutputStream(excelFileName);
XSSFWorkbook wb = new XSSFWorkbook();
XSSFCellStyle style = wb.createCellStyle();
XSSFSheet sheet = wb.createSheet("sheet");
Font urlFont = wb.createFont();
urlFont.setFontHeight((short)(9*20));
style.setFont(urlFont);
for (int r = 0; r < 3; r++) {
XSSFRow row = sheet.createRow(r);
for (int c = 0; c < 3; c++) {
XSSFCell cell = row.createCell(c);
Hyperlink link = wb.getCreationHelper().createHyperlink(HyperlinkType.URL);
String ss = "http://news.google.com/news/headlines?ned=us&hl=en";
link.setAddress(ss);
cell.setHyperlink(link);
cell.setCellValue(ss);
if(r == 1) {
System.out.println("In yellow");
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
style.setFillForegroundColor(new XSSFColor(Color.YELLOW));
} else {
System.out.println("In red");
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
style.setFillForegroundColor(new XSSFColor(Color.RED));
}
cell.setCellStyle(style);
}
}
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
wb.write(baos);
byte[] myByteArray = baos.toByteArray();
fos.write(myByteArray);
fos.flush();
}
finally {
wb.close();
fos.close();
}
}
}
To solve this issue, I could create 2 styles separately and apply them based on the condition but in a practical case I have to create 24 different styles but for that, I have to write so much redundant code.
If I want to create a new style with a different property then I have to create another 24 styles with this new property. Therefore the complexity will go exponentially.
Therefore, can anyone provide some suggestion on this issue?
I am using Java 8, excel and apache poi for my project. There are certain cell values that I am interested in extracting from excel using java. I am trying to detect text which is strikeout in the excel cells, but the format of text is little different that is why I am facing some problems.
Below is how data laid out in my excel sheet:
After extacting this data from excel, I always save it in string arraylist format like this a = [text 1, text 2, text 3]. code is mentioned below if you want to see how I am storing data in this arraylist.
What I want:
I want to ignore all those texts which are strikeout, so in above case I expect to have output like this [text 2, text 3] for first picture and second picture.
What I tried:
For the sake of just detecting strikeout values, I tried below code first:
XSSFRichTextString text = new XSSFRichTextString(a.get(0));
XSSFFont font = text.getFontAtIndex(0);
Boolean font_striked = font.getStrikeout();
but above code is not working as font_striked returns null, it must return true or false
The code which partially works in my case on single line cell values is:
boolean striked_out = sheet.getRow(row_index).getCell(column_index).getCellStyle().
getFont().getStrikeout();
This code only works if there is single line value in the cell and not with bullet list as shown above. It fails as it is not made for such kind of text.
P.S
I believe that if somehow I am able to detect even a single strikeout string in bullet points from arraylist, I can make it work for all the data.
As per the answer below I have updated my question adding following code to show how I make my string arraylist
How I convert data in excel into Arraylist:
String value_header = cell.getStringCellValue();
String[] newline_split = value_header.split("-");
for (int i = 0; i < newline_split.length; i++){
final_values = newline_split[i].
replace("\n"," ").replaceAll("\\s{2,}", " ").trim();
XSSFRichTextString text = new XSSFRichTextString(final_values);
XSSFFont font = text.getFontAtIndex(0);
Boolean font_striked = font.getStrikeout();
} // for ends here
You will need to get the RichTextString first, then go through all FormattingRuns, check whether it is stroked out and only if not, then get the appropriated substring and put it into the List:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.CellType.*;
import org.apache.poi.xssf.usermodel.*;
import java.io.FileInputStream;
import java.util.List;
import java.util.ArrayList;
class ReadExcelRichTextCells {
public static void main(String[] args) throws Exception {
Workbook wb = WorkbookFactory.create(new FileInputStream("ExcelRichTextCells.xlsx"));
Sheet sheet = wb.getSheetAt(0);
for (Row row : sheet) {
for (Cell cell : row) {
switch (cell.getCellTypeEnum()) {
case STRING:
XSSFRichTextString richtextstring = (XSSFRichTextString)cell.getRichStringCellValue();
String textstring = richtextstring.getString();
List<String> textparts = new ArrayList<String>();
if (richtextstring.hasFormatting()) {
for (int i = 0; i < richtextstring.numFormattingRuns(); i++) {
if (richtextstring.getFontOfFormattingRun(i)==null || !richtextstring.getFontOfFormattingRun(i).getStrikeout()) {
int indexofformattingrun = richtextstring.getIndexOfFormattingRun(i);
String textpart = textstring.substring(indexofformattingrun,
indexofformattingrun + richtextstring.getLengthOfFormattingRun(i));
String[] textpart_split = textpart.split("-");
for (int j = 0; j < textpart_split.length; j++){
String text = textpart_split[j].replace("\n", "").trim();
if (!"".equals(text)) textparts.add(text);
}
}
}
} else {
textparts.add(textstring);
}
System.out.println(textparts);
break;
//...
default:
System.out.println("default cell"); //should never occur
}
}
}
wb.close();
}
}
This is how to get the strikethrough in Excel with VBA:
Public Sub IsMyActivecellStriked()
Debug.Print ActiveCell.Font.Strikethrough
End Sub
If you have something like this:
Then the you should find a way to access the characters and check for them. Like this:
Option Explicit
Public Sub TestMe()
Dim strRange As String
Dim varArr As Variant
Dim varStr As Variant
Dim lngStart As Long
Dim lngEnd As Long
strRange = [a1]
varArr = Split(strRange, Chr(10))
For Each varStr In varArr
lngStart = InStr(1, strRange, varStr)
Debug.Print [a1].Characters(Start:=lngStart, Length:=Len(varStr)).Font.Strikethrough
Debug.Print [a1].Characters(Start:=lngStart, Length:=Len(varStr)).Text
Next varStr
End Sub
This will give you the following in the immediate window:
False
aaa
True
bbb
True
ccc
False
ddd
This should be possible to be translated into Java with the POI library.
As per I understanding above question Question (plz Correct me if I am wrong..!)
It should show whether your text in cell is strikethrough or not. ( TRUE or FALSE)
Below I have created a demo with that :
public class ApachePOI {
public static void main(String[] args) {
//Using workbook
XSSFWorkbook workbook;
try {
//Access excel file as workbook
workbook = new XSSFWorkbook(new FileInputStream(new File("/testExcelfile.xlsx")));
// first sheet of excel file
XSSFSheet xssfFirstSheet = workbook.getSheetAt(0);
//Check for A1 cell that strikethrough or not
boolean strikedOutTextStatus = xssfFirstSheet.getRow(0).getCell(0).getCellStyle().getFont().getStrikeout();
//print status of A1 cell text
System.out.println(strikedOutTextStatus);
// UPDATED CODE
if(strikedOutTextStatus){
String cellStringValue = xssfFirstSheet.getRow(0).getCell(0).getStringCellValue();
System.out.println("cell Value : "+cellStringValue.replace("-", "").replace(" ", ""));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}