上接
Java POI Excel sheet合并
http://zhuyufufu.iteye.com/blog/2033386
Java POI Excel sheet 合并遇到的问题解决
http://zhuyufufu.iteye.com/blog/2035033
http://zhuyufufu.iteye.com/blog/2036578
在合并sheet的时候,分页符的复制也是非常重要的,不然打印就会变形
//分页符的拷贝
int[] rowBreaks = sourceSheet.getRowBreaks();
for (int rowBreaksIndex = 0; rowBreaksIndex < rowBreaks.length; rowBreaksIndex++) {
targetSheet.setRowBreak(pPosition + rowBreaks[rowBreaksIndex]);
}
完整的复制代码
public static HSSFWorkbook mergeHSSFWorkbooks(HSSFWorkbook[] workbooks) {
if(workbooks == null || workbooks.length == 0){
return null;
}else if(workbooks.length == 1){
return workbooks[0];
}
HSSFWorkbook wbFirst = workbooks[0];
HSSFSheet toSheet = wbFirst.getSheetAt(0);
for (int i = 1; i < workbooks.length; i++) {
toSheet.setRowBreak(toSheet.getLastRowNum());
HSSFWorkbook wb = workbooks[i];
HSSFSheet fromsheet = wb.getSheetAt(0);
if(i == 1){
copyRows(wbFirst, wb, fromsheet, toSheet, fromsheet.getFirstRowNum(), fromsheet.getLastRowNum(), (toSheet.getLastRowNum() + 1));
}else{
copyRows(wbFirst, wb, fromsheet, toSheet, fromsheet.getFirstRowNum(), fromsheet.getLastRowNum(), (toSheet.getLastRowNum() + 1));
}
}
return wbFirst;
}
/**
* @param destWorkBook 目标workbook
* @param sourceWorkBook 源workbook
* @param sourceSheet 源sheet
* @param targetSheet 目sheet
* @param pStartRow 起始读取行
* @param pEndRow 结束读取行
* @param pPosition 目标保存
*/
public static void copyRows(HSSFWorkbook destWorkBook, HSSFWorkbook sourceWorkBook, HSSFSheet sourceSheet,HSSFSheet targetSheet, int pStartRow, int pEndRow, int pPosition) {
HSSFRow sourceRow = null;
HSSFRow targetRow = null;
HSSFCell sourceCell = null;
HSSFCell targetCell = null;
int cType;
int i;
int j;
int targetRowFrom;
int targetRowTo;
if ((pStartRow == -1) || (pEndRow == -1)) {
return;
}
List<CellRangeAddress> oldRanges = new ArrayList<CellRangeAddress>();
for (i = 0; i < sourceSheet.getNumMergedRegions(); i++) {
oldRanges.add(sourceSheet.getMergedRegion(i));
}
// 拷贝合并的单元格。原理:复制当前合并单元格后,原位置的格式会移动到新位置,需在原位置生成旧格式
for (int k = 0; k < oldRanges.size(); k++) {
CellRangeAddress oldRange = oldRanges.get(k);
CellRangeAddress newRange = new CellRangeAddress(oldRange
.getFirstRow(), oldRange.getLastRow(), oldRange
.getFirstColumn(), oldRange.getLastColumn());
if (oldRange.getFirstRow() >= pStartRow
&& oldRange.getLastRow() <= pEndRow) {
targetRowFrom = oldRange.getFirstRow() - pStartRow + pPosition;
targetRowTo = oldRange.getLastRow() - pStartRow + pPosition;
oldRange.setFirstRow(targetRowFrom);
oldRange.setLastRow(targetRowTo);
targetSheet.addMergedRegion(oldRange);
sourceSheet.addMergedRegion(newRange);
}
}
// 设置列宽
for (i = pStartRow; i <= pEndRow; i++) {
sourceRow = sourceSheet.getRow(i);
if (sourceRow != null) {
for (j = sourceRow.getLastCellNum(); j > sourceRow.getFirstCellNum(); j--) {
targetSheet.setColumnWidth(j, sourceSheet.getColumnWidth(j));
targetSheet.setColumnHidden(j, false);
}
break;
}
}
List<HSSFCellStyle> cellStyleList = new ArrayList<HSSFCellStyle>();
// 拷贝行并填充数据
for (; i <= pEndRow; i++) {
sourceRow = sourceSheet.getRow(i);
if (sourceRow == null) {
continue;
}
targetRow = targetSheet.createRow(i - pStartRow + pPosition);
targetRow.setHeight(sourceRow.getHeight());
for (j = sourceRow.getFirstCellNum(); j <= sourceRow.getPhysicalNumberOfCells(); j++) {
sourceCell = sourceRow.getCell(j);
if (sourceCell == null) {
continue;
}
targetCell = targetRow.createCell(j);
//复制样式
//样式的设置
HSSFCellStyle cStyle = compareStoreAndGetCellStyle(cellStyleList, sourceCell.getCellStyle(), destWorkBook, sourceWorkBook);
targetCell.setCellStyle(cStyle);
cType = sourceCell.getCellType();
targetCell.setCellType(cType);
switch (cType) {
case HSSFCell.CELL_TYPE_BOOLEAN:
targetCell.setCellValue(sourceCell.getBooleanCellValue());
// System.out.println("--------TYPE_BOOLEAN:" + targetCell.getBooleanCellValue());
break;
case HSSFCell.CELL_TYPE_ERROR:
targetCell.setCellErrorValue(sourceCell.getErrorCellValue());
// System.out.println("--------TYPE_ERROR:" + targetCell.getErrorCellValue());
break;
case HSSFCell.CELL_TYPE_FORMULA:
// parseFormula这个函数的用途在后面说明
targetCell.setCellFormula(parseFormula(sourceCell.getCellFormula()));
// System.out.println("--------TYPE_FORMULA:" + targetCell.getCellFormula());
break;
case HSSFCell.CELL_TYPE_NUMERIC:
targetCell.setCellValue(sourceCell.getNumericCellValue());
// System.out.println("--------TYPE_NUMERIC:" + targetCell.getNumericCellValue());
break;
case HSSFCell.CELL_TYPE_STRING:
targetCell.setCellValue(sourceCell.getRichStringCellValue());
// System.out.println("--------TYPE_STRING:" + i + targetCell.getRichStringCellValue());
break;
default:
targetCell.setCellValue(sourceCell.getRichStringCellValue());
// System.out.println("--------TYPE_STRING:" + i + targetCell.getRichStringCellValue());
break;
}
}
}
//分页符的拷贝
int[] rowBreaks = sourceSheet.getRowBreaks();
for (int rowBreaksIndex = 0; rowBreaksIndex < rowBreaks.length; rowBreaksIndex++) {
targetSheet.setRowBreak(pPosition + rowBreaks[rowBreaksIndex]);
}
}
/**
* 比较存储并获得cellstyle
* @param cellStyleList
* @param cellStyle
* @param sourceWorkBook
* @return
*/
private static HSSFCellStyle compareStoreAndGetCellStyle(
List<HSSFCellStyle> cellStyleList,
HSSFCellStyle sourceCellStyle,
HSSFWorkbook destWorkBook,
HSSFWorkbook sourceWorkBook) {
for (int index = 0; index < cellStyleList.size(); index++) {
HSSFCellStyle cellStyle = cellStyleList.get(index);
if(isEqual(cellStyle, sourceCellStyle, destWorkBook, sourceWorkBook)){
return cellStyle;
}
}
//拷贝新的样式到列表
HSSFCellStyle cStyle = destWorkBook.createCellStyle();
cStyle = copyCellStyle(cStyle, sourceCellStyle, sourceWorkBook);
cellStyleList.add(cStyle);
return cStyle;
}
/**
* 两个cellStyle是否相同
* @param cellStyle
* @param sourceCellStyle
* @param sourceWorkBook
* @param destWorkBook
* @return
*/
private static boolean isEqual(HSSFCellStyle cellStyle,
HSSFCellStyle sourceCellStyle, HSSFWorkbook destWorkBook, HSSFWorkbook sourceWorkBook) {
//判断换行样式是否一样
if(cellStyle.getWrapText() != sourceCellStyle.getWrapText()){
return false;
}
//对齐方式是否一样
if(cellStyle.getAlignment() != sourceCellStyle.getAlignment()){
return false;
}
if(cellStyle.getVerticalAlignment()!= sourceCellStyle.getVerticalAlignment()){
return false;
}
//边框是否一样
if(cellStyle.getBorderBottom()!= sourceCellStyle.getBorderBottom()){
return false;
}
if(cellStyle.getBorderLeft()!= sourceCellStyle.getBorderLeft()){
return false;
}
if(cellStyle.getBorderRight()!= sourceCellStyle.getBorderRight()){
return false;
}
if(cellStyle.getBorderTop()!= sourceCellStyle.getBorderTop()){
return false;
}
if(cellStyle.getBottomBorderColor()!= sourceCellStyle.getBottomBorderColor()){
return false;
}
if(cellStyle.getLeftBorderColor()!= sourceCellStyle.getLeftBorderColor()){
return false;
}
if(cellStyle.getRightBorderColor()!= sourceCellStyle.getRightBorderColor()){
return false;
}
if(cellStyle.getTopBorderColor()!= sourceCellStyle.getTopBorderColor()){
return false;
}
//字体是否一样
HSSFFont sourceFont = sourceCellStyle.getFont(sourceWorkBook);
HSSFFont destFont = cellStyle.getFont(destWorkBook);
if(destFont.getBoldweight() != sourceFont.getBoldweight()){
return false;
}
if(destFont.getCharSet() != sourceFont.getCharSet()){
return false;
}
if(destFont.getColor() != sourceFont.getColor()){
return false;
}
if(destFont.getColor() != sourceFont.getColor()){
return false;
}
if(destFont.getFontHeight() != sourceFont.getFontHeight()){
return false;
}
if(destFont.getFontHeightInPoints() != sourceFont.getFontHeightInPoints()){
return false;
}
if(destFont.getIndex() != sourceFont.getIndex()){
return false;
}
if(destFont.getItalic() != sourceFont.getItalic()){
return false;
}
if(destFont.getUnderline() != sourceFont.getUnderline()){
return false;
}
if(destFont.getStrikeout() != sourceFont.getStrikeout()){
return false;
}
if(!destFont.getFontName().equals(sourceFont.getFontName())){
return false;
}
//别的样式是否一样
return true;
}
/**
* 样式拷贝
* @param cStyle 目标style
* @param sourceCellStyle 源style
* @param sourceWorkBook 源workBook
* @return
*/
private static HSSFCellStyle copyCellStyle(HSSFCellStyle cStyle, HSSFCellStyle sourceCellStyle, HSSFWorkbook sourceWorkBook) {
if(sourceCellStyle == null || cStyle == null){
return cStyle;
}
//是否换行
cStyle.setWrapText(sourceCellStyle.getWrapText());
//字体拷贝
cStyle.setFont(sourceCellStyle.getFont(sourceWorkBook));
// cStyle.cloneStyleFrom(sourceCellStyle);
//拷贝对齐方式
cStyle.setAlignment(sourceCellStyle.getAlignment());
cStyle.setVerticalAlignment(sourceCellStyle.getVerticalAlignment());
//边框拷贝
cStyle.setBorderBottom(sourceCellStyle.getBorderBottom());
cStyle.setBorderLeft(sourceCellStyle.getBorderLeft());
cStyle.setBorderRight(sourceCellStyle.getBorderRight());
cStyle.setBorderTop(sourceCellStyle.getBorderTop());
cStyle.setBottomBorderColor(sourceCellStyle.getBottomBorderColor());
cStyle.setLeftBorderColor(sourceCellStyle.getLeftBorderColor());
cStyle.setRightBorderColor(sourceCellStyle.getRightBorderColor());
cStyle.setTopBorderColor(sourceCellStyle.getTopBorderColor());
//别的样式的拷贝
return cStyle;
}
/**
* 处理公式
* @param pPOIFormula
* @return
*/
private static String parseFormula(String pPOIFormula) {
final String cstReplaceString = "ATTR(semiVolatile)"; //$NON-NLS-1$
StringBuffer result = null;
int index;
result = new StringBuffer();
index = pPOIFormula.indexOf(cstReplaceString);
if (index >= 0) {
result.append(pPOIFormula.substring(0, index));
result.append(pPOIFormula.substring(index + cstReplaceString.length()));
} else {
result.append(pPOIFormula);
}
return result.toString();
}
分享到:
相关推荐
本项目“poi多线程大数据导出excel文件”提供了一个解决方案,利用多线程来提高Excel的大数据导出效率。 Apache POI 3.1版本是较早的版本,而项目中使用了更新的4.1版本,这意味着它可能利用了更多优化和新特性。在...
为解决此问题,可以在Excel中手动添加一个分页符,然后用POI打开文件并删除这个分页符,这样会触发POI为rowBreaks创建实例,之后便可以正常设置分页符。如果Sheet是由POI生成的,就不会出现此类问题。 其次,我们...
本文将深入探讨在使用POI进行Excel操作时遇到的一些常见问题及解决方案,特别是关于设置分页符的bug和如何复制行。 1. 设置分页符的bug: 在POI的HSSFSheet类中,setRowBreak方法用于设定工作表的分页符。然而,...
代码中还涉及到了数据库查询的部分,具体是通过`AgentOperRecordInfo`类进行数据的查询和分页,这部分代码与POI的使用关系不大,主要是为了获取要展示在Excel中的数据。这部分涉及到的具体业务逻辑和数据处理,需要...
Struts2和Apache POI是Java开发中两个重要的工具,它们在处理Web应用程序中的数据导出,特别是Excel表格导出方面发挥着重要作用。Struts2是一个基于MVC设计模式的Web应用框架,它极大地简化了Java Web开发。而Apache...
在实际开发中,可能还需要考虑一些细节问题,比如数据量大时的分页导出,单元格合并,条件格式化,以及错误处理等。同时,对于性能优化,可以采用SXSSFWorkbook,它是POI提供的一种低内存占用的API,可以实现只读取...
poi导入、导出,支持百万级数据模板导出、合并excel。项目为spring-boot-2上开发。resource里面有模板,在junit测试类中修改为本地存在路径即可导出文件,在junit测试类中修改for循环的i可以模拟百万级数据导出。注意...
POI是一个流行的Java库,用于读取和写入Microsoft Office格式的文件,包括Excel。它提供了一个基于事件模型的低内存占用API(SXSSF),适合处理大型数据集。然而,即使使用SXSSF,当数据量过大时,内存管理仍然是一...
本篇文章将深入探讨如何使用Apache POI将大量数据分页导出到Excel,以避免一次性导出数据过多导致的性能问题。 首先,我们来看关键的类`PoiUtil.java`。这个类通常会封装Apache POI的核心操作,如创建工作簿、工作...
标题“poi test”暗示了我们将讨论的是Apache POI库在处理Microsoft Office文档,特别是Excel文件时的应用。Apache POI是一个开源项目,它允许Java开发者读取、写入和修改多种Microsoft Office格式的文件,包括Excel...
通常,后端会使用如Python的pandas、Java的Apache POI等库来生成Excel文件,然后返回给前端下载。前端只需要发送一个包含所有分页参数的请求即可,例如: ```javascript $.ajax({ url: '/export/excel', type: '...
这个教程将探讨如何使用 POI 库导出 Excel 文件,包括创建一般表头、处理复杂表头以及实现分页功能。 首先,我们需要理解 POI 的基本概念。在 POI 中,Excel 文件被表示为 `Workbook`,而工作簿中的每个工作表则...
4. **分页处理数据**:在监听器中,可以利用Java的分页处理框架(如Spring Boot的Pageable)对数据进行分页,每读取完一页数据,就调用`writeHeader()`和`writeRowData()`方法将这一页的数据写入Excel。 5. **优化...
- 可以自定义样式、合并单元格等,以增强导出的Excel文件的可读性。 4. **SSM框架搭建**: - 配置Spring的XML文件,包括Bean定义、数据源、事务管理器等。 - 配置SpringMVC的DispatcherServlet,定义拦截器、...
Apache POI 是一个用于读写 Microsoft Office 格式文件(如 Excel 和 Word)的开源 Java 库。它支持多种格式,包括旧版的 .xls 文件和较新的 .xlsx 文件。本教程将详细介绍如何使用 Apache POI 的两个主要子项目:...
2. 创建模板:使用Microsoft Excel或类似的工具创建模板文件,使用特定的占位符标记数据位置。 3. 编写Java代码:定义数据模型,使用`jxls`提供的API加载模板,绑定数据,最后导出Excel文件。 4. 运行和测试:运行...
在Java编程领域,Apache POI 是一个非常流行的库...同时,他们需要考虑数据的分页、排序、过滤和样式设定,确保Excel文件的可读性和专业性。在实际项目中,通常会结合模板引擎,如XSSFFactory,来提高复用性和灵活性。