自己写的POIUtil,主要解决从不同的HSSFWorkbook复制sheet以及根据单元格插入图片等
复制sheet的原始代码网上找的,但是小问题很多,然后自己动手改了一下;
根据单元格信息动态插入图片,如果单元格有文字,图片的位置会在文字之后,如果同样的位置已有图片则会往下插入。
import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress; import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List; /**
* Created with IntelliJ IDEA.
* Author: Duelsol
* Date: 14-7-18
* Time: 下午4:05
*/
public class POIUtil { private static Logger logger = Logger.getLogger(POIUtil.class); private POIUtil() {} /**
* 复制工作表
* 此方法主要用于复制2个不同HSSFWorkbook间的工作表
*/
public static void copySheet(HSSFWorkbook fromWorkbook, HSSFWorkbook toWorkbook, int fromSheetIndex, int toSheetIndex) {
toWorkbook.setSheetName(toSheetIndex, fromWorkbook.getSheetName(fromSheetIndex));
HSSFSheet fromSheet = fromWorkbook.getSheetAt(fromSheetIndex);
for (int i = fromSheet.getFirstRowNum(); i <= fromSheet.getLastRowNum(); i++) {
copyRows(fromWorkbook, toWorkbook, fromSheetIndex, toSheetIndex, i, i, i);
}
} /**
* 复制行
* 此方法主要用于复制2个不同HSSFWorkbook间的行
*/
public static void copyRows(HSSFWorkbook fromWorkbook, HSSFWorkbook toWorkbook, int fromSheetIndex, int toSheetIndex, int startRow, int endRow, int position) {
HSSFSheet fromSheet = fromWorkbook.getSheetAt(fromSheetIndex);
HSSFSheet toSheet = toWorkbook.getSheetAt(toSheetIndex);
int i;
int j; if ((startRow == -1) || (endRow == -1)) {
return;
} List<CellRangeAddress> oldRanges = new ArrayList<CellRangeAddress>();
for (i = 0; i < fromSheet.getNumMergedRegions(); i++) {
oldRanges.add(fromSheet.getMergedRegion(i));
} // 拷贝合并的单元格。原理:复制当前合并单元格后,原位置的格式会移动到新位置,需在原位置生成旧格式
for (CellRangeAddress oldRange : oldRanges) {
CellRangeAddress newRange = new CellRangeAddress(oldRange.getFirstRow(), oldRange.getLastRow(),
oldRange.getFirstColumn(), oldRange.getLastColumn()); if (oldRange.getFirstRow() >= startRow && oldRange.getLastRow() <= endRow) {
int targetRowFrom = oldRange.getFirstRow() - startRow + position;
int targetRowTo = oldRange.getLastRow() - startRow + position;
oldRange.setFirstRow(targetRowFrom);
oldRange.setLastRow(targetRowTo);
toSheet.addMergedRegion(oldRange);
fromSheet.addMergedRegion(newRange);
}
} // 设置列宽
for (i = startRow; i <= endRow; i++) {
HSSFRow fromRow = fromSheet.getRow(i);
if (fromRow != null) {
for (j = fromRow.getLastCellNum(); j >= fromRow.getFirstCellNum(); j--) {
toSheet.setColumnWidth(j, fromSheet.getColumnWidth(j));
toSheet.setColumnHidden(j, false);
}
break;
}
} // 拷贝行并填充数据
for (; i <= endRow; i++) {
HSSFRow fromRow = fromSheet.getRow(i);
if (fromRow == null) {
continue;
}
HSSFRow toRow = toSheet.createRow(i - startRow + position);
toRow.setHeight(fromRow.getHeight());
for (j = fromRow.getFirstCellNum(); j <= fromRow.getPhysicalNumberOfCells(); j++) {
HSSFCell fromCell = fromRow.getCell(j);
if (fromCell == null) {
continue;
}
HSSFCell toCell = toRow.createCell(j);
HSSFCellStyle toStyle = toWorkbook.createCellStyle();
copyCellStyle(fromWorkbook, toWorkbook, fromCell.getCellStyle(), toStyle);
toCell.setCellStyle(toStyle);
int cType = fromCell.getCellType();
toCell.setCellType(cType);
switch (cType) {
case HSSFCell.CELL_TYPE_BOOLEAN:
toCell.setCellValue(fromCell.getBooleanCellValue());
// System.out.println("--------TYPE_BOOLEAN:" +
// targetCell.getBooleanCellValue());
break;
case HSSFCell.CELL_TYPE_ERROR:
toCell.setCellErrorValue(fromCell.getErrorCellValue());
// System.out.println("--------TYPE_ERROR:" +
// targetCell.getErrorCellValue());
break;
case HSSFCell.CELL_TYPE_FORMULA:
toCell.setCellFormula(parseFormula(fromCell.getCellFormula()));
// System.out.println("--------TYPE_FORMULA:" +
// targetCell.getCellFormula());
break;
case HSSFCell.CELL_TYPE_NUMERIC:
toCell.setCellValue(fromCell.getNumericCellValue());
// System.out.println("--------TYPE_NUMERIC:" +
// targetCell.getNumericCellValue());
break;
case HSSFCell.CELL_TYPE_STRING:
toCell.setCellValue(fromCell.getRichStringCellValue());
// System.out.println("--------TYPE_STRING:" + i +
// targetCell.getRichStringCellValue());
break;
}
}
}
} /**
* 复制行
* 如果是同一个HSSFWorkbook中的行请用此方法
*/
public static void copyRows(HSSFWorkbook workbook, int fromSheetIndex, int toSheetIndex, int startRow, int endRow, int position) {
HSSFSheet fromSheet = workbook.getSheetAt(fromSheetIndex);
HSSFSheet toSheet = workbook.getSheetAt(toSheetIndex);
int i;
int j; if ((startRow == -1) || (endRow == -1)) {
return;
} List<CellRangeAddress> oldRanges = new ArrayList<CellRangeAddress>();
for (i = 0; i < fromSheet.getNumMergedRegions(); i++) {
oldRanges.add(fromSheet.getMergedRegion(i));
} // 拷贝合并的单元格。原理:复制当前合并单元格后,原位置的格式会移动到新位置,需在原位置生成旧格式
for (CellRangeAddress oldRange : oldRanges) {
CellRangeAddress newRange = new CellRangeAddress(oldRange.getFirstRow(), oldRange.getLastRow(),
oldRange.getFirstColumn(), oldRange.getLastColumn()); if (oldRange.getFirstRow() >= startRow && oldRange.getLastRow() <= endRow) {
int targetRowFrom = oldRange.getFirstRow() - startRow + position;
int targetRowTo = oldRange.getLastRow() - startRow + position;
oldRange.setFirstRow(targetRowFrom);
oldRange.setLastRow(targetRowTo);
toSheet.addMergedRegion(oldRange);
fromSheet.addMergedRegion(newRange);
}
} // 设置列宽
for (i = startRow; i <= endRow; i++) {
HSSFRow fromRow = fromSheet.getRow(i);
if (fromRow != null) {
for (j = fromRow.getLastCellNum(); j >= fromRow.getFirstCellNum(); j--) {
toSheet.setColumnWidth(j, fromSheet.getColumnWidth(j));
toSheet.setColumnHidden(j, false);
}
break;
}
} // 拷贝行并填充数据
for (; i <= endRow; i++) {
HSSFRow fromRow = fromSheet.getRow(i);
if (fromRow == null) {
continue;
}
HSSFRow toRow = toSheet.createRow(i - startRow + position);
toRow.setHeight(fromRow.getHeight());
for (j = fromRow.getFirstCellNum(); j <= fromRow.getPhysicalNumberOfCells(); j++) {
HSSFCell fromCell = fromRow.getCell(j);
if (fromCell == null) {
continue;
}
HSSFCell toCell = toRow.createCell(j);
toCell.setCellStyle(fromCell.getCellStyle());
int cType = fromCell.getCellType();
toCell.setCellType(cType);
switch (cType) {
case HSSFCell.CELL_TYPE_BOOLEAN:
toCell.setCellValue(fromCell.getBooleanCellValue());
// System.out.println("--------TYPE_BOOLEAN:" +
// targetCell.getBooleanCellValue());
break;
case HSSFCell.CELL_TYPE_ERROR:
toCell.setCellErrorValue(fromCell.getErrorCellValue());
// System.out.println("--------TYPE_ERROR:" +
// targetCell.getErrorCellValue());
break;
case HSSFCell.CELL_TYPE_FORMULA:
toCell.setCellFormula(parseFormula(fromCell.getCellFormula()));
// System.out.println("--------TYPE_FORMULA:" +
// targetCell.getCellFormula());
break;
case HSSFCell.CELL_TYPE_NUMERIC:
toCell.setCellValue(fromCell.getNumericCellValue());
// System.out.println("--------TYPE_NUMERIC:" +
// targetCell.getNumericCellValue());
break;
case HSSFCell.CELL_TYPE_STRING:
toCell.setCellValue(fromCell.getRichStringCellValue());
// System.out.println("--------TYPE_STRING:" + i +
// targetCell.getRichStringCellValue());
break;
}
}
}
} /**
* 复制单元格样式
* 此方法主要用于复制2个不同HSSFWorkbook间的单元格样式
*/
public static void copyCellStyle(HSSFWorkbook fromWorkbook, HSSFWorkbook toWorkbook, HSSFCellStyle fromStyle, HSSFCellStyle toStyle) {
toStyle.setAlignment(fromStyle.getAlignment()); // 边框和边框颜色
toStyle.setBorderBottom(fromStyle.getBorderBottom());
toStyle.setBorderLeft(fromStyle.getBorderLeft());
toStyle.setBorderRight(fromStyle.getBorderRight());
toStyle.setBorderTop(fromStyle.getBorderTop());
toStyle.setTopBorderColor(fromStyle.getTopBorderColor());
toStyle.setBottomBorderColor(fromStyle.getBottomBorderColor());
toStyle.setRightBorderColor(fromStyle.getRightBorderColor());
toStyle.setLeftBorderColor(fromStyle.getLeftBorderColor()); // 字体
HSSFFont tofont = toWorkbook.createFont();
copyFont(fromStyle.getFont(fromWorkbook), tofont);
toStyle.setFont(tofont); // 背景和前景
toStyle.setFillBackgroundColor(fromStyle.getFillBackgroundColor());
toStyle.setFillForegroundColor(fromStyle.getFillForegroundColor()); toStyle.setDataFormat(fromStyle.getDataFormat());
toStyle.setFillPattern(fromStyle.getFillPattern());
toStyle.setHidden(fromStyle.getHidden());
toStyle.setIndention(fromStyle.getIndention());
toStyle.setLocked(fromStyle.getLocked());
toStyle.setRotation(fromStyle.getRotation());
toStyle.setVerticalAlignment(fromStyle.getVerticalAlignment());
toStyle.setWrapText(fromStyle.getWrapText());
} /**
* 复制字体
* 此方法主要用于复制2个不同HSSFWorkbook间的字体
*/
public static void copyFont(HSSFFont fromFont, HSSFFont toFont) {
toFont.setBoldweight(fromFont.getBoldweight());
toFont.setCharSet(fromFont.getCharSet());
toFont.setColor(fromFont.getColor());
toFont.setFontHeight(fromFont.getFontHeight());
toFont.setFontHeightInPoints(fromFont.getFontHeightInPoints());
toFont.setFontName(fromFont.getFontName());
toFont.setItalic(fromFont.getItalic());
toFont.setStrikeout(fromFont.getStrikeout());
toFont.setTypeOffset(fromFont.getTypeOffset());
toFont.setUnderline(fromFont.getUnderline());
} private static String parseFormula(String pPOIFormula) {
final String cstReplaceString = "ATTR(semiVolatile)"; //$NON-NLS-1$
StringBuffer result;
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();
} /**
* 根据单元格信息动态插入图片,如果单元格有文字,图片的位置会在文字之后,如果同样的位置已有图片则会往下插入
*
* @param workbook Excel
* @param cell 单元格信息
* @param inputStream 图片输入流
* @param scale 图片缩放,传入null表示原始尺寸,其余表示图片高于行高的比(例如传入1.5,表示该图片占1.5个行高)
*/
public static void createPicture(HSSFWorkbook workbook, HSSFCell cell, InputStream inputStream, Double scale) {
ByteArrayOutputStream byteArrayOut = null;
try {
byteArrayOut = new ByteArrayOutputStream();
BufferedImage bufferImg = ImageIO.read(inputStream);
ImageIO.write(bufferImg, "png", byteArrayOut); if (cell != null && (cell.getCellType() == HSSFCell.CELL_TYPE_STRING || cell.getCellType() == HSSFCell.CELL_TYPE_BLANK)) {
HSSFSheet sheet = cell.getSheet();
HSSFRow row = cell.getRow();
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
String cellValue = cell.getStringCellValue().contains("#{") ? cell.getStringCellValue().split("#\\{")[0] : cell.getStringCellValue(); int i = row.getRowNum();
short j = (short) cell.getColumnIndex(); int colWidth = sheet.getColumnWidth(cell.getColumnIndex()) / 32; // 单元格像素宽度
int wordWidth = cellValue.getBytes("GBK").length == 0 ? 0 : ((cellValue.getBytes("GBK").length + 2) * 8); // 单元格文本大致像素宽度
double pert = new BigDecimal(wordWidth).divide(new BigDecimal(colWidth), 10, BigDecimal.ROUND_HALF_UP).doubleValue(); int dx1 = new BigDecimal(pert * 1023).setScale(0, BigDecimal.ROUND_HALF_UP).intValue();
int dy1 = 0; List<HSSFShape> shapes = sheet.getDrawingPatriarch().getChildren();
for (HSSFShape shape : shapes) {
HSSFClientAnchor anchor = (HSSFClientAnchor) shape.getAnchor();
if (anchor.getRow1() == i && anchor.getCol1() == j && anchor.getDx1() == dx1 && anchor.getDy1() == dy1) {
if (anchor.getDy2() >= 255) {
i = anchor.getRow2() + 1;
dy1 = 0;
} else {
i = anchor.getRow2();
dy1 = anchor.getDy2() + 1;
}
}
} HSSFClientAnchor anchor = new HSSFClientAnchor(dx1, dy1, 0, 0, j, i, j, i + 1); // 由于用了getPreferredSize所以dx2,dy2无效
anchor.setAnchorType(3);
if (scale == null) {
patriarch.createPicture(anchor, workbook.addPicture(byteArrayOut.toByteArray(), HSSFWorkbook.PICTURE_TYPE_PNG)).getPreferredSize(1.0);
} else {
double zoom = new BigDecimal(row.getHeight() / 15).divide(new BigDecimal(bufferImg.getHeight()), 10, BigDecimal.ROUND_HALF_UP).doubleValue(); // 行高像素与图片高度像素比例
patriarch.createPicture(anchor, workbook.addPicture(byteArrayOut.toByteArray(), HSSFWorkbook.PICTURE_TYPE_PNG)).getPreferredSize(zoom * scale);
}
}
} catch (IOException ioe) {
logger.error("插入图片失败", ioe);
} finally {
if (byteArrayOut != null) {
try {
byteArrayOut.close();
} catch (IOException e) {
logger.error("关闭ByteArrayOutputStream失败", e);
}
}
}
} }
自己写的POIUtil,主要解决从不同的HSSFWorkbook复制sheet以及根据单元格插入图片等的更多相关文章
- 工作总结 1 sql写法 insert into select from 2 vs中 obj文件和bin文件 3 npoi 模板copy CopySheet 最好先全部Copy完后 再根据生成sheet写数据 4 sheet.CopyRow(rowsindex, rowsindex + x); 5 npoi 复制模板如果出现单元格显示问题
我们可以从一个表中复制所有的列插入到另一个已存在的表中: INSERT INTO table2SELECT * FROM table1; 或者我们可以只复制希望的列插入到另一个已存在的表中: INSE ...
- C#操作Word,写数据,插入图片
本篇介绍的是如何在C#中往word里面写入数据. 如何在线的操作文档: c#在线操作文档 关于Aspose.Word控件的介绍,请戳→ 介绍 首先需要去下载这个dll文件,然后引用到你的项目当中.地 ...
- (解决)easypoi图片导出只占用一个单元格
@ 目录 前提 依赖环境 问题原因 解决方案 重写jar中的方法 原理 前提 本解决方案来源于网络,因解决自己需求,因此自行记录起来,如有侵权请联系我. 依赖环境 easypoi--依赖版本3.1.0 ...
- slickgrid ( nsunleo-slickgrid ) 4 解决点击不切换单元格的问题
slickgrid ( nsunleo-slickgrid ) 4 解决点击不切换单元格的问题 上一次解决了列选择和区域选择冲突的问题,昨天太忙了,并且要陪小宝早点睡觉,就啥也没有赶上.今天上班面试. ...
- Flex4 DataGrid实现可复制单元格,同时解决自定义GridItemRenderer出现1009错误的方法
原创内容,如需转载,请注明出处,谢谢 最近在项目中发现Flex的DataGrid不支持内容复制,在涉及到保护敏感数据时倒是很有用处,但大部分情况下,我们还是希望客户能够直接复制DataGrid单元格中 ...
- 填报表导出excel非可写单元格锁定问题
问题描述: 填报表单元格分为可写和不可写两种状态,当填报表在web上展现的时候可写单元格可以进行数据填报和修改,非可写单元格不可操作. 报表导出为excel时,润乾导出excel包默认情况下不对 ...
- 填报表导出excel后不可写的单元格处于锁定状态
填报表单元格分为可写和不可写两种状态,当填报表在web上展现的时候可写单元格可以进行数据填报和修改,非可写单元格不可操作. 报表导出为excel时,润乾导出excel包默认情况下不对excel单 ...
- beyond compare解决特殊字符无法输出、多sheet页无法对比以及文件太大超出系统内存问题的Excel转txt脚本
beyond compare解决特殊字符无法输出.多sheet页无法对比以及文件太大超出系统内存问题的Excel转txt脚本 ' XLS_to_CSV.vbs ' ' Converts an Exce ...
- Npoi XWPF Word 导出时插入图片无法显示 bug 完美解决
一.来自客户的需求 最近客户来个新需求生成一个word 标签纸,并且需要在标签纸上插入一个logo,并且将erp 中的数据取出来自动写在文档上,不由得淡淡一笑,这不难呀! 于是乎我就写下了这样的代码: ...
随机推荐
- crontab 添加sh文件定时
(1)编写sh文件,比如/orcl/test/export.sh 编写crond文件 chmod 755 /orcl/test/* //复制所有权限 [root@postest test]# ...
- 大数据揭示的10个常见JAVA编程错误
初学者最常犯的编程错误是什么呢?有可能他们总是混淆等值(==)与赋值(=),或者 & 和 &&:也有可能是他们在循环中使用错误的分隔符(for (int i = 0, i &l ...
- underScore学习1:匿名函数中call(this)的作用
匿名函数中(function(){}).call(this) 中的.call(this) 有什么用? 我们都知道,.call()可以改变函数执行时的context,即this的指向,源码中的.call ...
- H264的coded_block_pattern编码块模式
1 词汇约定 CodedBlockPatternLuma:一个宏块的亮度分量的coded_block_pattern CodedBlockPatternChroma:一个宏块的色度分量的coded_b ...
- iOS摇一摇功能、震动功能、简单的摇动动画、生成二维码图片与发送短信等几个功能
有一个开锁的功能,具体的需求就类似于微信的"摇一摇"功能:摇动手机,手机震动,手机上的锁的图片摇动一下,然后发送开锁指令.需求简单,但用到了许多方面的知识. 1.摇一摇 相对这是最 ...
- 移动端ios电话号码
<meta name="format-detection" content="telephone=no"> <meta http-equiv= ...
- 使用mybatis多表联查的时候结果异常及springmvc的理解
今天使用mybatis多表联查的时候,在dos窗口查询时可以出结果集,但是使用mybatis查询的时候最后返回的结果只有最后一个结果 然后研究了半天没弄出来,后来无意中发现添加了最外层从表的ID字段后 ...
- tflearn save模型异常
存储模型始终无法形成单个文件,最初以为是机器中间断电\休眠引起的,重复了3次之后,发现这个问题一直存在.(每一次都要跑8~9个小时啊,摔...) 解决办法:tensorflow的版本回退到0.11版 ...
- Linux中变量#,#,@,0,0,1,2,2,*,$$,$?的含义
$# 是传给脚本的参数个数 $0 是脚本本身的名字 $1 是传递给该shell脚本的第一个参数 $2 是传递给该shell脚本的第二个参数 $@ 是传给脚本的所有参数的列表 $* 是以一个单字符串显示 ...
- 更新sdk
更新sdk,遇到了更新下载失败问题: Fetching https://dl-ssl.google.com/android/repository/addons_list-2.xmlFetched Ad ...