Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。.NET的开发人员则可以利用NPOI (POI for .NET) 来存取 Microsoft Office文档的功能。
提示:下文代码示例有Java和Kotlin形式
PS: 目前不确定此库能否在Android平台上使用,但从Github上的搜索结果来看,应该需要移植
包名称说明
目前只研究了读写表格的相关操作,至于Word等其他文件还没有细致研究,之后有研究了再补充了..
首先,先引入依赖
<!--xls(03)-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.0.0</version>
</dependency>
<!--xlsx(07)-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.0.0</version>
</dependency>
poi是只支持xls格式,而poi-ooxml则可以支持xlsx格式
上面我们也是知道,由于存在两种格式,所以我们的写法上得注意一下
XSSFWorkbook 对应xls文件HSSFWorkbook 对应xlsx文件由于XSSFWorkbook和HSSFWorkbook都是实现的Workbook接口,所以可利用到多态的原理来编写代码,达到兼容写法
fun main(args: Array<String>) {
val file = File("D:\\download\\test.xlsx")
var workbook: Workbook? = null
if (file.extension.toLowerCase() == "xlsx") {
//xlsx
workbook = XSSFWorkbook(file)
}
if (file.extension.toLowerCase() == "xls") {
//xls
workbook = HSSFWorkbook(FileInputStream(file))
}
workbook?.let {
val sheet = workbook.getSheetAt(0)
//读取第一行第一列单元格数据
val firstColumn = sheet.getRow(0).first()
//需要判断一下但单元格的类型
if (firstColumn.cellType == CellType.STRING) {
println(firstColumn.stringCellValue)
}
workbook.close()
}
}
PS:就是觉得有些神奇的是,XSSFWorkbook构造函数可以接收File类型的对象参数,而HSSFWorkbook只能接收FileInputSteam
val file = File("D:\\download\\myoutput.xlsx")
val workbook: Workbook = XSSFWorkbook()
//val workbook: Workbook = HSSFWorkbook()
val sheet = workbook.createSheet("sheet0")
val row = sheet.createRow(0)
val cell = row.createCell(0)
cell.cellType = CellType.STRING
cell.setCellValue("hello world")
//输出到文件
workbook.write(FileOutputStream(file))
workbook.close()
效果:

可以查看此教程Apache POI Word(docx) 入门示例教程
暂无需求,还没有细研究
除此之外,可以选择Word模板然后注入对应的数据进去,推荐使用Poi-tl Documentation
POIFSFileSystem fs=newPOIFSFileSystem(new FileInputStream("d:/test.xls"));
//得到Excel工作簿对象
HSSFWorkbook wb = new HSSFWorkbook(fs);
//得到Excel工作表对象
HSSFSheet sheet = wb.getSheetAt(0);
//得到Excel工作表的行
HSSFRow row = sheet.getRow(0);
//得到Excel工作表指定行的单元格
HSSFCell cell = row.getCell(0);
//得到单元格样式
cellStyle = cell.getCellStyle();
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");
HSSFRow row = sheet.createRow((short)0);
HSSFCell cell = sheet.createCell((short)0);
cellStyle = wb.createCellStyle();
//指定单元格样式和值
cell.setCellStyle(cellStyle);
cell.setCellValue(1);
//设置sheet名称
wb.setSheetName(0, "12" + "月合同到期");
//取得sheet的数目
wb.getNumberOfSheets();
//新建名称为Output的sheet
HSSFSheet sheet = wb.createSheet("Output");
//根据index取得sheet对象
HSSFSheet sheet = wb.getSheetAt(0);
//选中指定的工作表
sheet.setSelected(true);
//取得有效的行数
int rowcount = sheet.getLastRowNum();
//取得一行的有效单元格个数
row.getLastCellNum();
//根据单元格不同属性返回字符串数值
public String getCellStringValue(HSSFCell cell) {
String cellValue = "";
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_STRING://字符串类型
cellValue = cell.getStringCellValue();
if(cellValue.trim().equals("")||cellValue.trim().length()<=0) {
cellValue=" ";
}
break;
case HSSFCell.CELL_TYPE_NUMERIC: //数值类型
cellValue = String.valueOf(cell.getNumericCellValue());
break;
case HSSFCell.CELL_TYPE_FORMULA: //公式
cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
cellValue = String.valueOf(cell.getNumericCellValue());
break;
case HSSFCell.CELL_TYPE_BLANK:
cellValue=" ";
break;
case HSSFCell.CELL_TYPE_BOOLEAN:
break;
case HSSFCell.CELL_TYPE_ERROR:
break;
default:
break;
}
return cellValue;
}
//设置单元格为STRING类型
cell.setCellType(HSSFCell.CELL_TYPE_STRING);
//设置单元格的值---有重载
cell.setCellValue(value);

POI CellType类型有以下几种
| CellType类型 | 值 |
|---|---|
| CELL_TYPE_NUMERIC | 数值型 0 |
| CELL_TYPE_STRING | 字符串型 1 |
| CELL_TYPE_FORMULA | 公式型 2 |
| CELL_TYPE_BLANK | 空值 3 |
| CELL_TYPE_BOOLEAN | 布尔型 4 |
| CELL_TYPE_ERROR | 错误 5 |
使用POI读取单元格的数据有两种方式:
setCellType将单元格类型设置为字符串,然后通过getRichStringCellValue读取该单元格数据,然后将读取到的字符串转换为对应的类型,getCellType获取单元格类型,然后通过对应的getcellvalue方法读取该单元格数据,如:getNumericCellValuesheet.setColumnWidth((short)column,(short)width);
row.setHeight((short)height);
//POI设置自适应列宽sheet.autoSizeColumn(i); (版本不能太老)
sheet.autoSizeColumn(i, true);(合并的单元格使用)
sheet.setColumnWidth(i, “列名”.getBytes().length*2*256);(中文适用)
公式单元格自适应的是公式,将值算出后再设置:
HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet.getWorkbook());
CellValue cell71Val = evaluator.evaluate(cell71);
cell71.setCellValue(cell71Val.getNumberValue());
//调整单元格宽度
sheet.setAutobreaks(true);
sheet.setColumnWidth((short)i,colsWidth[i]); //设定单元格长度
sheet.autoSizeColumn((short) i);//自动根据长度调整单元格长度
//合并从第rowFrom行columnFrom列
Region region = new Region((short)rowFrom,(short)columnFrom,(short)rowTo ,(short)columnTo);
sheet.addMergedRegion(region);// 到rowTo行columnTo的区域
// 获得一个 sheet 中合并单元格的数量
int sheetmergerCount = sheet.getNumMergedRegions();
HSSFCellStyle style = wb.createCellStyle();
style.setBorderBottom(HSSFCellStyle.BORDER_DOTTED);//下边框
style.setBorderLeft(HSSFCellStyle.BORDER_DOTTED);//左边框
style.setBorderRight(HSSFCellStyle.BORDER_THIN);//右边框
style.setBorderTop(HSSFCellStyle.BORDER_THIN);//上边框

其中边框类型分为以下几种:
| 边框范例图 | 对应的静态值 |
|---|---|
![]() |
HSSFCellStyle. BORDER_DOTTED |
![]() |
HSSFCellStyle. BORDER_HAIR |
![]() |
HSSFCellStyle. BORDER_DASH_DOT_DOT |
![]() |
HSSFCellStyle. BORDER_DASH_DOT |
![]() |
HSSFCellStyle. BORDER_DASHED |
![]() |
HSSFCellStyle. BORDER_THIN |
![]() |
HSSFCellStyle. BORDER_MEDIUM_DASH_DOT_DOT |
![]() |
HSSFCellStyle. BORDER_SLANTED_DASH_DOT |
![]() |
HSSFCellStyle. BORDER_MEDIUM_DASH_DOT |
![]() |
HSSFCellStyle. BORDER_MEDIUM_DASHED |
![]() |
HSSFCellStyle. BORDER_MEDIUM |
![]() |
HSSFCellStyle. BORDER_THICK |
![]() |
HSSFCellStyle. BORDER_DOUBLE |
HSSFFont font = wb.createFont();
font.setFontName("华文行楷");//设置字体名称
font.setFontHeightInPoints((short) 11); //字号
font.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL); //加粗
font.setColor(HSSFColor.RED.index); //设置字体颜色
font.setUnderline(FontFormatting.U_SINGLE); //设置下划线
font.setTypeOffset(FontFormatting.SS_SUPER);//设置上标下标
font.setStrikeout(true); //设置删除线
style.setFont(font);
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);//左右居中
style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//上下居中
style.setRotation(short rotation);//单元格内容的旋转的角度
Style.setWrapText(true); //设置excel单元格中的内容换行
HSSFDataFormat df = wb.createDataFormat();
style1.setDataFormat(df.getFormat("0.00%"));//设置单元格数据格式
cell.setCellStyle(style);
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("row sheet");
// Create various cells and rows for spreadsheet.
// Shift rows 6 - 11 on the spreadsheet to the top (rows 0 - 5)
sheet.shiftRows(5, 10, -5);
HSSFCellStyle style = wb.createCellStyle();
style.setFillBackgroundColor(HSSFColor.AQUA.index);
style.setFillPattern(HSSFCellStyle.BIG_SPOTS);
HSSFCell cell = row.createCell((short) 1);
cell.setCellValue("X");
style = wb.createCellStyle();
style.setFillForegroundColor(HSSFColor.ORANGE.index);
style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
cell.setCellStyle(style);
sheet.setZoom(1,2); // 50 percent magnification
sheet.setZoom(75); //75% scale
cell.setCellType(XSSFCell.CELL_TYPE_FORMULA);
cell.setCellFormula("SUM(C2:C3)" ); //给单元格设公式
cell.setCellFormula("hyperlink(\"http://www.yiibai.com/testng/\",\"testng\")");
public static void test1(){
FileOutputStream fileOut = null;
BufferedImage bufferImg = null;
try {
ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
//加载图片
bufferImg = ImageIO.read(new File(picture));
ImageIO.write(bufferImg, "jpg", byteArrayOut);
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("sheet1");
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
HSSFClientAnchor anchor = new HSSFClientAnchor(0,0,1023,255,(short) 0,0,(short)4,37);
//插入图片 1
patriarch.createPicture(anchor, wb.addPicture(byteArrayOut.toByteArray(), HSSFWorkbook.PICTURE_TYPE_JPEG));
//图片2
anchor = new HSSFClientAnchor(500, 0, 0, 0,(short) 5, 1, (short) 9, 38);
patriarch.createPicture(anchor, wb.addPicture(byteArrayOut.toByteArray(), HSSFWorkbook.PICTURE_TYPE_JPEG));
fileOut = new FileOutputStream( filepath+"/excel.xls");
// 输出文件
wb.write(fileOut);
System.out.println("test1");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void test3(){
FileOutputStream fileOut = null;
BufferedImage bufferImg = null;
try {
ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
//加载图片
bufferImg = ImageIO.read(new File(picture));
ImageIO.write(bufferImg, "jpg", byteArrayOut);
XSSFWorkbook wb = new XSSFWorkbook();
XSSFSheet sheet1 = wb.createSheet("sheet1");
XSSFDrawing drawing = sheet1.createDrawingPatriarch();
XSSFClientAnchor anchor = new XSSFClientAnchor(0,0,1023,255,(short) 0,0,(short)10,10);
//插入图片 1
drawing.createPicture(anchor, wb.addPicture(byteArrayOut.toByteArray(), HSSFWorkbook.PICTURE_TYPE_JPEG));
fileOut = new FileOutputStream( filepath+ "/excel2.xlsx");
// 输出文件
wb.write(fileOut);
System.out.println("test3");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void testread(){
InputStream inp;
try {
inp = new FileInputStream(filepath+"/excel.xls");
HSSFWorkbook workbook = new HSSFWorkbook(inp);//读取现有的Excel文件
List<HSSFPictureData> pictures = workbook.getAllPictures();
for(int i=0;i<pictures.size();i++){
HSSFPictureData pic=pictures.get(i);
String ext = pic.suggestFileExtension();
if (ext.equals("jpeg"))//判断文件格式,依照实际图片格式设置
{
FileOutputStream png=new FileOutputStream(filepath +"\\Apache.jpg");
png.write(pic.getData());
png.close();//保存图片
System.out.println("test11");
}
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
我想为我的Rails网络应用程序提供推荐功能。特别是,我想向新注册的用户推荐他可能想要关注的其他用户。Rails中是否有用于此目的的引擎/gem?如果没有,我应该从哪里开始构建它?谢谢。 最佳答案 有Coletivogemhttps://github.com/diogenes/coletivo我试了一下。在MySQL上运行。Neo4jhttp://neo4j.org真的很容易实现一个“跟随谁”。事实上,大多数展示其能力的样本都涉及“跟随谁”。快速提示-只有在JRuby上运行时,Neo4j.rb才会很酷。如果不是-使用Neograph
matlab打开matlab,用最简单的imread方法读取一个图像clcclearimg_h=imread('hua.jpg');返回一个数组(矩阵),往往是a*b*cunit8类型解释一下这个三维数组的意思,行数、数和层数,unit8:指数据类型,无符号八位整形,可理解为0~2^8的数三个层数分别代表RGB三个通道图像rgb最常用的是24-位实现方法,即RGB每个通道有256色阶(2^8)。基于这样的24-位RGB模型的色彩空间可以表现256×256×256≈1670万色当imshow传入了一个二维数组,它将以灰度方式绘制;可以把图像拆分为rgb三层,可以以灰度的方式观察它figure(1
您将如何构建一个简单的Sinatra应用程序?我正在制作,我希望该应用具有以下功能:“应用程序”更像是一个包含所有信息的管理仪表板。然后另一个应用程序将通过REST访问信息。我还没有创建仪表板,只是从数据库中获取东西session和身份验证(尚未实现)您可以上传图片,其他应用可以显示这些图片我已经使用RSpec创建了一个测试文件通过Prawn生成报告目前的设置是这样的:app.rbtest_app.rb因为我实际上只有应用程序和测试文件。到目前为止,我已经将Datamapper用于ORM,将SQLite用于数据库。这是我的第一个Ruby/Sinatra项目,所以欢迎任何和所有建议-我应
我对图像处理完全陌生。我对JPEG内部是什么以及它是如何工作一无所知。我想知道,是否可以在某处找到执行以下简单操作的ruby代码:打开jpeg文件。遍历每个像素并将其颜色设置为fx绿色。将结果写入另一个文件。我对如何使用ruby-vips库实现这一点特别感兴趣https://github.com/ender672/ruby-vips我的目标-学习如何使用ruby-vips执行基本的图像处理操作(Gamma校正、亮度、色调……)任何指向比“helloworld”更复杂的工作示例的链接——比如ruby-vips的github页面上的链接,我们将不胜感激!如果有ruby-
我有一个super简单的脚本,它几乎包含了FayeWebSocketGitHub页面上用于处理关闭连接的内容:ws=Faye::WebSocket::Client.new(url,nil,:headers=>headers)ws.on:opendo|event|p[:open]#sendpingcommand#sendtestcommand#ws.send({command:'test'}.to_json)endws.on:messagedo|event|#hereistheentrypointfordatacomingfromtheserver.pJSON.parse(event.d
我正在尝试解析网页,但有时会收到404错误。这是我用来获取网页的代码:result=Net::HTTP::getURI.parse(URI.escape(url))如何测试result是否为404错误代码? 最佳答案 像这样重写你的代码:uri=URI.parse(url)result=Net::HTTP.start(uri.host,uri.port){|http|http.get(uri.path)}putsresult.codeputsresult.body这将打印状态码和正文。
Ruby有一些不错的文档生成器,例如Yard、rDoc,甚至Glyph。问题是Sphinx可以做网站、PDF、epub、LaTex等。它在重组文本中完成所有这些事情。在Ruby世界中有替代方案吗?也许是程序的组合?如果我也能使用Markdown就更好了。 最佳答案 自1.0版以来,Sphinx有了“域”的概念,它是从Python和/或C以外的语言标记代码实体(如方法调用、对象、函数等)的方法。有一个rubydomain,所以你可以只使用Sphinx本身。您唯一会缺少的(我认为)是Sphinx使用autodoc从源代码自动创建文档
我查看了Stripedocumentationonerrors,但我仍然无法正确处理/重定向这些错误。基本上无论发生什么,我都希望他们返回到edit操作(通过edit_profile_path)并向他们显示一条消息(无论成功与否)。我在edit操作上有一个表单,它可以POST到update操作。使用有效的信用卡可以正常工作(费用在Stripe仪表板中)。我正在使用Stripe.js。classExtrasController5000,#amountincents:currency=>"usd",:card=>token,:description=>current_user.email)
我怀念ipython的一件事是它有一个?为特定功能挖掘文档的运算符。我知道ruby有一个类似的命令行工具,但是我在irb中调用它非常不方便。ruby/irb有类似的东西吗? 最佳答案 Pry是IPython的Ruby版本,它支持?命令来查找有关方法的文档,但语法略有不同:pry(main)>?File.dirnameFrom:file.cinRubyCore(CMethod):Numberoflines:6visibility:publicsignature:dirname()Returnsallcomponentsofthef