问题场景
今天项目用到POI对Excel读取功能,其中需求方还要求Excel里设置斜体的文字在PDF里展示成斜体。
处理思路
在用itext写PDF过程中,要同时在一个段落里展示斜体和正常字体并不难,给需要斜体的文字加一个标签再处理下即可。按照这个思路,再用POI读取Excel内容,读到斜体部分给它加一个标签对。
code
package poi;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Created by yangyouxing
* date on 2017/8/14.
*/
public class ReadExcelItalic {
/**
* 增加了识别斜体标志 <i></i>
* 读取单元格的值
* @param cell
* @param wb
* @return
*/
@SuppressWarnings("deprecation")
public static String getCellValue(HSSFCell cell, Workbook wb) {
Object result = "";
//如果单元格为空,返回null
if (cell != null) {
switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
HSSFRichTextString textString = cell.getRichStringCellValue();
char [] stringArr = textString.toString().toCharArray();
StringBuffer sb = new StringBuffer();
boolean ks = true; //开始斜体
boolean js = true; //结束斜体
for (int p = 0; p < textString.length(); p++) {//遍历单元格
boolean italic = cell.getCellStyle().getFont(wb).getItalic();
if (italic) {
if (ks) {
sb.append("<i>");
ks = false;
}
sb.append(stringArr[p]);
if (p == textString.length() - 1) {
sb.append("</i>");
}
} else {
if (!ks && js) {
sb.append("</i>");
js = true; //重置标志位
ks = true; //重置标志位
}
sb.append(stringArr[p]);
}
}
result = sb.toString();
break;
// 数字类型
case Cell.CELL_TYPE_NUMERIC:
// 处理日期格式、时间格式
if (HSSFDateUtil.isCellDateFormatted(cell)) {
SimpleDateFormat sdf = null;
if (cell.getCellStyle().getDataFormat() == HSSFDataFormat.getBuiltinFormat("h:mm")) {
sdf = new SimpleDateFormat("HH:mm");
} else {// 日期
sdf = new SimpleDateFormat("yyyy-MM-dd");
}
Date date = cell.getDateCellValue();
result = sdf.format(date);
} else if (cell.getCellStyle().getDataFormat() == 58) {
// 处理自定义日期格式:m月d日(通过判断单元格的格式id解决,id的值是58)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
double value = cell.getNumericCellValue();
Date date = org.apache.poi.ss.usermodel.DateUtil.getJavaDate(value);
result = sdf.format(date);
}
else if(cell.getCellStyle().getDataFormatString().indexOf("%") != -1){
//百分比处理
BigDecimal a1 = new BigDecimal(Double.toString(cell.getNumericCellValue()));
BigDecimal b1 = new BigDecimal(Double.toString(100));
// 相乘结果 小数位 直接舍去
BigDecimal resultVal = a1.multiply(b1).setScale(2, BigDecimal.ROUND_DOWN);
result = resultVal.toString()+"%";
}else if(!isCellEmpty(cell) && cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
// 返回数值类型的值
Object inputValue = null;// 单元格值
Long longVal = Math.round(cell.getNumericCellValue());
Double doubleVal = cell.getNumericCellValue();
if(Double.parseDouble(longVal + ".0") == doubleVal){ //判断是否含有小数位.0
inputValue = longVal;
result = inputValue;
}else{
inputValue = doubleVal;
DecimalFormat df = new DecimalFormat("0.00"); //
result = String.valueOf(df.format(inputValue)); //返回String类型
}
}
break;
case Cell.CELL_TYPE_BOOLEAN:
result = cell.getBooleanCellValue();
break;
//公式处理
case HSSFCell.CELL_TYPE_FORMULA:
try {
/*
* 此处判断使用公式生成的字符串有问题,因为HSSFDateUtil.isCellDateFormatted(cell)判断过程中cell
* .getNumericCellValue();方法会抛出java.lang.NumberFormatException异常
*/
if (HSSFDateUtil.isCellDateFormatted(cell)) {
Date date = cell.getDateCellValue();
result = (date.getYear() + 1900) + "-" + (date.getMonth() + 1) +"-" + date.getDate();
break;
} else {
result = String.valueOf(cell.getNumericCellValue());
}
} catch (IllegalStateException e) {
result = String.valueOf(cell.getRichStringCellValue());
}
break;
case Cell.CELL_TYPE_ERROR:
result = cell.getErrorCellValue();
break;
default:
break;
}
}
return result.toString();
}
/**
* 读取Excel文件
* @param localFile
* @param path
*/
private void readExcel(File localFile, String path) {
//对临时文件做Excel操作
Workbook book = null;
InputStream is = null;
try {
is = new FileInputStream(localFile);
if (path.toLowerCase().endsWith(".xlsx")) {
book = new XSSFWorkbook(is);
} else if (path.toLowerCase().endsWith(".xls")) {
book = new HSSFWorkbook(is);
}
// 获得第一个工作表对象
HSSFSheet sheet = (HSSFSheet) book.getSheetAt(0);
int rows = sheet.getLastRowNum();
HSSFRow row = null;
String result = null;
// 遍历每行每列的单元格
for (int i = 1; i < rows + 1; i++) {
row = sheet.getRow(i);
//row为空行,不做处理
if (!isRowEmpty(row)) {
int columns = row.getLastCellNum();
for (int j = 0; j < columns; j++) {
//给斜体加标签
result = getCellValue(row.getCell(j), book);
System.out.println(result);
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (book != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
/**
* 判断Excel单元格是空的
* @param cell
* @return
*/
public static boolean isCellEmpty(Cell cell) {
boolean res = false;
if (cell != null && cell.getCellType() == Cell.CELL_TYPE_BLANK)
res = true;
return res;
}
/**
* 判断Excel的一行为空
* @param row
* @return
*/
public static boolean isRowEmpty(Row row) {
for (int c = row.getFirstCellNum(); c < row.getLastCellNum(); c++) {
Cell cell = row.getCell(c);
if (cell != null && cell.getCellType() != Cell.CELL_TYPE_BLANK)
return false;
}
return true;
}