复制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. 工作总结 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 ...

  2. C#操作Word,写数据,插入图片

    本篇介绍的是如何在C#中往word里面写入数据. 如何在线的操作文档:  c#在线操作文档 关于Aspose.Word控件的介绍,请戳→ 介绍 首先需要去下载这个dll文件,然后引用到你的项目当中.地 ...

  3. (解决)easypoi图片导出只占用一个单元格

    @ 目录 前提 依赖环境 问题原因 解决方案 重写jar中的方法 原理 前提 本解决方案来源于网络,因解决自己需求,因此自行记录起来,如有侵权请联系我. 依赖环境 easypoi--依赖版本3.1.0 ...

  4. slickgrid ( nsunleo-slickgrid ) 4 解决点击不切换单元格的问题

    slickgrid ( nsunleo-slickgrid ) 4 解决点击不切换单元格的问题 上一次解决了列选择和区域选择冲突的问题,昨天太忙了,并且要陪小宝早点睡觉,就啥也没有赶上.今天上班面试. ...

  5. Flex4 DataGrid实现可复制单元格,同时解决自定义GridItemRenderer出现1009错误的方法

    原创内容,如需转载,请注明出处,谢谢 最近在项目中发现Flex的DataGrid不支持内容复制,在涉及到保护敏感数据时倒是很有用处,但大部分情况下,我们还是希望客户能够直接复制DataGrid单元格中 ...

  6. 填报表导出excel非可写单元格锁定问题

     问题描述: 填报表单元格分为可写和不可写两种状态,当填报表在web上展现的时候可写单元格可以进行数据填报和修改,非可写单元格不可操作. 报表导出为excel时,润乾导出excel包默认情况下不对 ...

  7. 填报表导出excel后不可写的单元格处于锁定状态

     填报表单元格分为可写和不可写两种状态,当填报表在web上展现的时候可写单元格可以进行数据填报和修改,非可写单元格不可操作. 报表导出为excel时,润乾导出excel包默认情况下不对excel单 ...

  8. beyond compare解决特殊字符无法输出、多sheet页无法对比以及文件太大超出系统内存问题的Excel转txt脚本

    beyond compare解决特殊字符无法输出.多sheet页无法对比以及文件太大超出系统内存问题的Excel转txt脚本 ' XLS_to_CSV.vbs ' ' Converts an Exce ...

  9. Npoi XWPF Word 导出时插入图片无法显示 bug 完美解决

    一.来自客户的需求 最近客户来个新需求生成一个word 标签纸,并且需要在标签纸上插入一个logo,并且将erp 中的数据取出来自动写在文档上,不由得淡淡一笑,这不难呀! 于是乎我就写下了这样的代码: ...

随机推荐

  1. VS生成桌面应用程序

    1.简介 1/ 什么是WPF WPF,Windows Presentation Foundation也,译过来就是"Windows呈现基础",你看它的目的非常明确,就是用来把数据& ...

  2. Defraggler(磁盘整理软件) V2.21.993 绿色版

    软件名称: Defraggler(磁盘整理软件) 软件语言: 简体中文 授权方式: 免费软件 运行环境: Win 32位/64位 软件大小: 5.0MB 图片预览: 软件简介: Defraggler ...

  3. YUM变量

    有一个简单的python命令可以看到yum的 releaserver.arch.basearch的值 /usr/bin/python -c 'import yum, pprint; yb = yum. ...

  4. USACO 3.2 Factorials

    Factorials The factorial of an integer N, written N!, is the product of all the integers from 1 thro ...

  5. November 12th 2016 Week 46th Saturday

    Never love anyone who treats you like you are ordinary. 请爱那些爱你的人. Don't waste your limited energy on ...

  6. could not resolve property问题(ssh框架)

    could not resolve property不能解析属性问题, 刚开始把hql语句中的"from User user where user.user_name = '"+u ...

  7. jquery 操作listbox 左右相互选择

    实现左右两个listbox的相互选择功能 代码如下: function ListBox_Move(listfrom, listto) { var size = $j("#" + l ...

  8. VMware下安装CentOS6.5

    一.工具 1.VMware-workstation-full-12.5.0-4352439.exe 2.CentOS-6.5-x86_64-minimal.iso 二.安装VMware虚拟机 1.选择 ...

  9. removeObjectAtIndex

    CGFloat lableW = (baseViewWidth - 2)/3;// dcj20150724,减2是为了解决字体模糊的问题,因为设置了边框. 原因是下面引起的 titleview.lay ...

  10. cmake+qt+qtcreator的配置,解决Q_OBJECT的问题

    1.如果在编译qt项目的时候,一般头文件里都有Q_OBJECT,但是用cmake来编译的时候,就会报错,那么怎么解决呢? 解决的办法就是要在cmake里面写好配置 命令,再编译的时候,就不会报错了,写 ...