需求:按提供的excel表格式,从数据仓把相应数据捞出填入
解决方案:直接读入现有excel,对相应格填相应数值,不改变原有excel表的格式
数据准备的实体类:
package com.followme.printExcel.vo;
import java.util.HashMap;
import java.util.Map;
public class newExcelDTO {
private Map<Short, Map<Short, String>> map = new HashMap<Short, Map<Short, String>>();
public Map<Short, Map<Short, String>> getMap() {
return map;
}
/**
* strLocation excel表的位置 格式 “B,4”,strValue对应格的数值
*/
public void setMap(String strLocation,String strValue) {
Map<Short, String> mapcell = new HashMap<Short, String>();
int iIndex = strLocation.indexOf(",");
String strColumn = strLocation.substring(0, iIndex);
int iColumn = letterToNumber(strColumn) - 1;
int iLine = Integer.parseInt(strLocation.substring(iIndex+1)) - 1;
//String strLine = String.valueOf(iLine);//因为有减1运算,所以算完再转换
if(map.containsKey((short) iLine)) {//如果已经有该行的数据,则取出列数据图做插入
/*Map<Short, String> mapcellold = map.get((short) iLine);
mapcell.putAll(mapcellold);
mapcell.put((short) iColumn, strValue);
map.put((short) iLine,mapcell);*/
mapcell = map.get((short) iLine);
mapcell.put((short) iColumn, strValue);
}else {
mapcell.put((short) iColumn, strValue);
map.put((short) iLine,mapcell);
}
}
/**
* 将以字母表示的Excel列数转换成数字表示
*
* @author WuQianLing
* @param letter
* 以字母表示的列数,不能为空且只允许包含字母字符
* @return 返回转换的数字,转换失败返回-1
*/
public int letterToNumber(String letter) {
// 检查字符串是否为空
if (letter == null || letter.isEmpty()) {
return -1;
}
String upperLetter = letter.toUpperCase(); // 转为大写字符串
if (!upperLetter.matches("[A-Z]+")) { // 检查是否符合,不能包含非字母字符
return -1;
}
long num = 0; // 存放结果数值
long base = 1;
// 从字符串尾部开始向头部转换
for (int i = upperLetter.length() - 1; i >= 0; i--) {
char ch = upperLetter.charAt(i);
num += (ch - 'A' + 1) * base;
base *= 26;
if (num > Integer.MAX_VALUE) { // 防止内存溢出
return -1;
}
}
return (int) num;
}
/**
* 将数字转换成以字母表示的Excel列数
*
* @author WuQianLing
* @param num
* 表示列数的数字
* @return 返回转换的字母字符串,转换失败返回null
*/
public String numberToLetter(int num) {
if (num <= 0) { // 检测列数是否正确
return null;
}
StringBuffer letter = new StringBuffer();
do {
--num;
int mod = num % 26; // 取余
letter.append((char) (mod + 'A')); // 组装字符串
num = (num - mod) / 26; // 计算剩下值
} while (num > 0);
return letter.reverse().toString(); // 返回反转后的字符串
}
}
实现数据输入及excel输出:
package com.followme.printExcel.vo;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.ServletOutputStream;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class ll {
public static void main(String[] args) {
newExcelDTO newExcelDTO = new newExcelDTO();
newExcelDTO.setMap("c,4", "123");
newExcelDTO.setMap("d,4", "1234");
newExcelDTO.setMap("E,4", "12345");
newExcelDTO.getMap();
String excelPath = "E:\\hxl\\test\\123.xlsx";
excelPath = new String(excelPath.getBytes("iso-8859-1"), "utf-8");
InputStream is = new FileInputStream(excelPath);
XSSFWorkbook wb = new XSSFWorkbook(is);
this.outExcel_xlsx(newExcelDTO.getMap(), wb,0);
wb.write(out);
}
private void outExcel_xlsx( Map<Short, Map<Short, String>> map, XSSFWorkbook wb,int iSheetIndex)
throws IOException, Exception {
XSSFSheet sheet1 = wb.getSheetAt(iSheetIndex);
// excel设置公式自动计算
sheet1.setForceFormulaRecalculation(true);
for (Entry<Short, Map<Short, String>> entry : map.entrySet()) {
XSSFRow row = sheet1.getRow((short) (entry.getKey()));
Map<Short, String> mapcell = entry.getValue();
for (Entry<Short, String> entryCell : mapcell.entrySet()) {
XSSFCell cell = row.getCell((short) (entryCell.getKey()));
String dataNumber = entryCell.getValue();
cell.setCellValue(new XSSFRichTextString(dataNumber));
// cell.setCellValue(Double.parseDouble(dataNumber));
// cell.setCellStyle(style);
}
}
}
}