1. POI 生成WORD文档为什么WORD文档打不开
Jacob解决Word文档的读写问题收藏
Jacob 是java-COM Bridge的缩写,它在Java与微软的COM组件之间构建一座桥梁。使用Jacob自带的DLL动态链接库,并通过JNI的方式实现了在Java平台上对COM程序的调用。Jacob下载的地址为:
http://sourceforge.net/project/showfiles.php?group_id=109543&package_id=118368
配置:
(1)将解压包中的jacob.dll(x86常用,x64)拷到jdk安装目录下的jre\bin文件夹或windows安装路径下的WINDOWS\system32文件夹下
(2)将jacob.jar文件拷到classpath下即可
常见问题解决:
对于”java.lang.UnsatisfiedLinkError: C:\WINDOWS\system32\jacob-1.14.3-x86.dll: 由于应用程序配置不正确,应用程序未能启动。重新安装应用程序可能会纠正”这个问题,可以通过
重新下载Jacob的jar及dll文件(最好版本比现在的低,如1.11)解决
实例制作(主要功能:标题制作,表格制作,合并表格,替换文本,页眉页脚,书签处理):
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
public class WordOperate {
public static void main(String args[]) {
ActiveXComponent wordApp = new ActiveXComponent("Word.Application"); // 启动word
// Set the visible property as required.
Dispatch.put(wordApp, "Visible", new Variant(true));// //设置word可见
Dispatch docs = wordApp.getProperty("Documents").toDispatch();
// String inFile = "d:\\test.doc";
// Dispatch doc = Dispatch.invoke(docs, "Open", Dispatch.Method,
// new Object[] { inFile, new Variant(false), new Variant(false)},//参数3,false:可写,true:只读
// new int[1]).toDispatch();//打开文档
Dispatch document = Dispatch.call(docs, "Add").toDispatch();// create new document
String userName = wordApp.getPropertyAsString("Username");// 显示用户信息
System.out.println("用户名:" + userName);
// 文档对齐,字体设置////////////////////////
Dispatch selection = Dispatch.get(wordApp, "Selection").toDispatch();
Dispatch align = Dispatch.get(selection, "ParagraphFormat")
.toDispatch(); // 行列格式化需要的对象
Dispatch font = Dispatch.get(selection, "Font").toDispatch(); // 字型格式化需要的对象
// 标题处理////////////////////////
Dispatch.put(align, "Alignment", "1"); // 1:置中 2:靠右 3:靠左
Dispatch.put(font, "Bold", "1"); // 字型租体
Dispatch.put(font, "Color", "1,0,0,0"); // 字型颜色红色
Dispatch.call(selection, "TypeText", "Word文档处理"); // 写入标题内容
Dispatch.call(selection, "TypeParagraph"); // 空一行段落
Dispatch.put(align, "Alignment", "3"); // 1:置中 2:靠右 3:靠左
Dispatch.put(selection, "Text", " ");
Dispatch.call(selection, "MoveDown"); // 光标标往下一行
//表格处理////////////////////////
Dispatch tables = Dispatch.get(document, "Tables").toDispatch();
Dispatch range = Dispatch.get(selection, "Range").toDispatch();
Dispatch table1 = Dispatch.call(tables, "Add", range, new Variant(3),
new Variant(2), new Variant(1)).toDispatch(); // 设置行数,列数,表格外框宽度
// 所有表格
Variant tableAmount = Dispatch.get(tables, "count");
System.out.println(tableAmount);
// 要填充的表格
Dispatch t1 = Dispatch.call(tables, "Item", new Variant(1))
.toDispatch();
Dispatch t1_row = Dispatch.get(t1, "rows").toDispatch();// 所有行
int t1_rowNum = Dispatch.get(t1_row, "count").getInt();
Dispatch.call(Dispatch.get(t1, "columns").toDispatch(), "AutoFit");// 自动调整
int t1_colNum = Dispatch.get(Dispatch.get(t1, "columns").toDispatch(),
"count").getInt();
System.out.println(t1_rowNum + " " + t1_colNum);
for (int i = 1; i <= t1_rowNum; i++) {
for (int j = 1; j <= t1_colNum; j++) {
Dispatch cell = Dispatch.call(t1, "Cell", new Variant(i),
new Variant(j)).toDispatch();// 行,列
Dispatch.call(cell, "Select");
Dispatch.put(selection, "Text", "cell" + i + j); // 写入word的内容
Dispatch.put(font, "Bold", "0"); // 字型租体(1:租体 0:取消租体)
Dispatch.put(font, "Color", "1,1,1,0"); // 字型颜色
Dispatch.put(font, "Italic", "1"); // 斜体 1:斜体 0:取消斜体
Dispatch.put(font, "Underline", "1"); // 下划线
Dispatch Range = Dispatch.get(cell, "Range").toDispatch();
String cellContent = Dispatch.get(Range, "Text").toString();
System.out.println((cellContent.substring(0, cellContent
.length() - 1)).trim());
}
Dispatch.call(selection, "MoveDown"); // 光标往下一行(才不会输入盖过上一输入位置)
}
//合并单元格////////////////////////
Dispatch.put(selection, "Text", " ");
Dispatch.call(selection, "MoveDown"); // 光标标往下一行
Dispatch range2 = Dispatch.get(selection, "Range").toDispatch();
Dispatch table2 = Dispatch.call(tables, "Add", range2, new Variant(8),
new Variant(4), new Variant(1)).toDispatch(); // 设置行数,列数,表格外框宽度
Dispatch t2 = Dispatch.call(tables, "Item", new Variant(2))
.toDispatch();
Dispatch beginCell = Dispatch.call(t2, "Cell", new Variant(1),
new Variant(1)).toDispatch();
Dispatch endCell = Dispatch.call(t2, "Cell", new Variant(4),
new Variant(4)).toDispatch();
Dispatch.call(beginCell, "Merge", endCell);
for (int row = 1; row <= Dispatch.get(
Dispatch.get(t2, "rows").toDispatch(), "count").getInt(); row++) {
for (int col = 1; col <= Dispatch.get(
Dispatch.get(t2, "columns").toDispatch(), "count").getInt(); col++) {
if (row == 1) {
Dispatch cell = Dispatch.call(t2, "Cell", new Variant(1),
new Variant(1)).toDispatch();// 行,列
Dispatch.call(cell, "Select");
Dispatch.put(font, "Color", "1,1,1,0"); // 字型颜色
Dispatch.put(selection, "Text", "merge Cell!");
} else {
Dispatch cell = Dispatch.call(t2, "Cell", new Variant(row),
new Variant(col)).toDispatch();// 行,列
Dispatch.call(cell, "Select");
Dispatch.put(font, "Color", "1,1,1,0"); // 字型颜色
Dispatch.put(selection, "Text", "cell" + row + col);
}
}
Dispatch.call(selection, "MoveDown");
}
//Dispatch.call(selection, "MoveRight", new Variant(1), new Variant(1));// 取消选择
// Object content = Dispatch.get(doc,"Content").toDispatch();
// Word文档内容查找及替换////////////////////////
Dispatch.call(selection, "TypeParagraph"); // 空一行段落
Dispatch.put(align, "Alignment", "3"); // 1:置中 2:靠右 3:靠左
Dispatch.put(font, "Color", 0);
Dispatch.put(selection, "Text", "欢迎,Hello,world!");
Dispatch.call(selection, "HomeKey", new Variant(6));// 移到开头
Dispatch find = Dispatch.call(selection, "Find").toDispatch();// 获得Find组件
Dispatch.put(find, "Text", "hello"); // 查找字符串"hello"
Dispatch.put(find, "Forward", "True");// 向前查找
// Dispatch.put(find, "Format", "True");// 设置格式
Dispatch.put(find, "MatchCase", "false");// 大小写匹配
Dispatch.put(find, "MatchWholeWord", "True"); // 全字匹配
Dispatch.call(find, "Execute"); // 执行查询
Dispatch.put(selection, "Text", "你好");// 替换为"你好"
//使用方法传入的参数parameter调用word文档中的MyWordMacro宏//
//Dispatch.call(document,macroName,parameter);
//Dispatch.invoke(document,macroName,Dispatch.Method,parameter,new int[1]);
//页眉,页脚处理////////////////////////
Dispatch ActiveWindow = wordApp.getProperty("ActiveWindow")
.toDispatch();
Dispatch ActivePane = Dispatch.get(ActiveWindow, "ActivePane")
.toDispatch();
Dispatch View = Dispatch.get(ActivePane, "View").toDispatch();
Dispatch.put(View, "SeekView", "9"); //9是设置页眉
Dispatch.put(align, "Alignment", "1"); // 置中
Dispatch.put(selection, "Text", "这里是页眉"); // 初始化时间
Dispatch.put(View, "SeekView", "10"); // 10是设置页脚
Dispatch.put(align, "Alignment", "2"); // 靠右
Dispatch.put(selection, "Text", "这里是页脚"); // 初始化从1开始
//书签处理(打开文档时处理)////////////////////////
//Dispatch activeDocument = wordApp.getProperty("ActiveDocument").toDispatch();
Dispatch bookMarks = Dispatch.call(document, "Bookmarks").toDispatch();
boolean isExist = Dispatch.call(bookMarks, "Exists", "bookMark1")
.getBoolean();
if (isExist == true) {
Dispatch rangeItem1 = Dispatch.call(bookMarks, "Item", "bookMark1")
.toDispatch();
Dispatch range1 = Dispatch.call(rangeItem1, "Range").toDispatch();
Dispatch.put(range1, "Text", new Variant("当前是书签1的文本信息!"));
String bookMark1Value = Dispatch.get(range1, "Text").toString();
System.out.println(bookMark1Value);
} else {
System.out.println("当前书签不存在,重新建立!");
Dispatch.call(bookMarks, "Add", "bookMark1", selection);
Dispatch rangeItem1 = Dispatch.call(bookMarks, "Item", "bookMark1")
.toDispatch();
Dispatch range1 = Dispatch.call(rangeItem1, "Range").toDispatch();
Dispatch.put(range1, "Text", new Variant("当前是书签1的文本信息!"));
String bookMark1Value = Dispatch.get(range1, "Text").toString();
System.out.println(bookMark1Value);
}
//保存操作////////////////////////
Dispatch.call(document, "SaveAs", "D:/wordOperate.doc");
//Dispatch.invoke((Dispatch) doc, "SaveAs", Dispatch.Method, new Object[]{htmlPath, new Variant(8)}, new int[1]); //生成html文件
// 0 = wdDoNotSaveChanges
// -1 = wdSaveChanges
// -2 = wdPromptToSaveChanges
//Dispatch.call(document, "Close", new Variant(0));
// // worddoc.olefunction("protect",2,true,"");
// // Dispatch bookMarks = wordApp.call(docs,"Bookmarks").toDispatch();
// // System.out.println("bookmarks"+bookMarks.getProgramId());
// //Dispatch.call(doc, "Save"); //保存
// // Dispatch.call(doc, "Close", new Variant(true));
// //wordApp.invoke("Quit",new Variant[]{});
// wordApp.safeRelease();//Finalizers call this method
}
2. 现有MYSQL数据库,如果要制作复杂的EXCEL报表改怎么办
如果你会制作复杂的EXCEL报表,那剩下的问题就是怎样把MYSQL数据库的数据导到EXCEL里了,这一般需要编写一个程序将把MYSQL数据库的数据导到EXCEL里(要是这个程序不会写那就上网搜搜看能不能搜到,或者再发一个问题问,或者请会的人写)。
如果你把MYSQL数据库的数据导到EXCEL里之后还是不会制作复杂的EXCEL报表,那你就要好好学学EXCEL报表的制作了。
3. phpid=传参的问题
问题出在: 1、echo "<li><a href='proct_detail.php?id=".$_GET['id']."'>".$row_RS1["name"]."</a></li>";$_GET['id']应改为$row_RS1['id'] 2、……echo $RS['content'];//问题出在你没有用mysql_fetch_array生成数据集就直接调用$RS['content']进行输出,所以不能正常显示你要的结果。 下面是修改后的页面: proct.php页面 <?php $conn = mysql_connect("localhost","root","qwepoi") or die ("链接失败"); mysql_select_db("web3"); mysql_query("SET NAMES 'utf8'"); $sql1 = "SELECT * FROM `proct` WHERE type = 'reactor'"; $RS1 = mysql_query($sql1); ?> ------------------------------------- <?php while ($row_RS1 = mysql_fetch_array($RS1)){ echo "<li><a href='proct_detail.php?id=".$row_RS1['id']."'>".$row_RS1["name"]."</a></li>"; } ?> ==================================================== proct_detail.php页面 <?php $conn = mysql_connect("localhost","root","qwepoi") or die ("链接失败"); mysql_select_db("web3"); mysql_query("SET NAMES 'utf8'"); $id = $_GET['id']; $sql = "SELECT * FROM `proct` WHERE id=".$id; $RS = mysql_query($sql); $row=mysql_fetch_array($RS); ?> ------------------------------------------------------ <?php echo $row['content'];?>
4. js如何用AJAX请求 $.post获取php中的数据poi_lng/poi_lat/poi2_lng/poi2_lat
$.post("../traffic/php/realtime.php",function(data){})中function的参数data就是后台返回的数据,php看不懂,不晓得你这个php返回的是个什么数据。你可以直接在浏览器的地址栏中输入那个php页面的地址访问一下看回来的数据是什么样的。
5. PHP5 点击新闻列表显示新闻内容页面怎么做
proct.php页面
<?php
$conn = mysql_connect("localhost","root","qwepoi") or die ("链接失败");
mysql_select_db("web3");
mysql_query("SET NAMES 'utf8'");
$sql1 = "SELECT * FROM `proct` WHERE type = 'reactor'";
$RS1 = mysql_query($sql1);
while ($row_RS1 = mysql_fetch_array($RS1)) {
echo "<li><a href='proct_detail.php?id=".$row_RS1['id']."'>".$row_RS1["name"]."</a></li>";
}
?>
proct_detail.php页面
<?php
$conn = mysql_connect("localhost","root","qwepoi") or die ("链接失败");
mysql_select_db("web3");
mysql_query("SET NAMES 'utf8'");
$id = $_GET['id'];
$sql = "SELECT * FROM `proct` WHERE `id`=$id";
$RS = mysql_query($sql);
echo $RS['content'];
?>
6. 求凯立德最新的凯立德POI格式的地图
采纳我的意见,然后给我消息,给我联系方式,我发给你
7. 百度地图 poi 类型总共有哪些
用php写后台程序,连接数据库! http://dev..com/wiki/static/map/API/examples/?v=1.3&3_0#3&0 里面的自家数据+前端搜索可供参考!
8. Java poi怎么导入
本篇面向对象为Java的初学者,从下载必备软件到创建一个空白的POI工程,已经熟练掌握环境搭建的请跳过此文。
开发环境为windowsXP-SP2,Eclipse3.2,JDK1.5.07,其实差不多都行,不会有太大的差异。本文从POI下载开始讲解,前提是开发环境包括系统变量等等已经正确设置完毕。
1.POI的下载
截至本文发表,POI最新版本是3.0.1,距离上一个Final版本有3年了吧,以至于我差点儿就把他放弃了——以为没人管了。官方的公告讲,这一版主要是追加了一些新的特性和BUG修正,不过稍微有点儿遗憾的是,还不能很好的操作Excel2007。
POI官方网址:
•http://poi.apache.org/
JAR包下载:
•http://apache.mirror.phpchina.com/poi/release/bin/poi-bin-3.0.1-FINAL-20070705.zip
源码下载:
•http://apache.mirror.phpchina.com/poi/release/src/poi-src-3.0.1-FINAL-20070705.zip
下载上面的JAR和源码(源码不是必须的,但是为了早日修得正果,深入系统的看看POI代码还是有必要的)并解压待用。
2.用Eclipse搭建项目
• 打开Eclipse
•依次点击File->New->Java Project
•输入项目名称,本例中设置为POI
•单击完成
•在项目上点击右键->New->Folder
•输入文件夹名称lib
•把刚才解压的poi-3.0.1-FINAL-20070705.jar复制过来
•右键点击项目,选择Properties
•在左侧列表里选中Java Build Path,右侧选中Libraries
•点击Add JARs,选择POI项目的lib下的所有文件
•两次OK确认,回到Eclipse界面
小技巧,快捷操作:可以用鼠标左键选中poi-3.0.1-FINAL-20070705.jar但不松开,拖到任务栏的Eclipse图标上等候1秒左右,Eclipse会自动弹起来,依然不松开移动到lib文件夹上,这个时候鼠标后面跟个十字符号,松开左键,就完成了复制动作。这个是对整个windows系统都好用的快捷复制方式,视源盘符和目标盘符的不同偶尔会用到Ctrl键。
到此为止,我们做好了POI学习的前提准备,接下来将从最简单的文档创建开始一步一步学习怎样让POI更好的为我们工作。
第一讲 :基本的Excel读写
本文主要演示一下POI的基本操作,例如怎样读取和创建一个具体的Excel文件。按照惯例,拿HelloWorld说事儿。
说明:本文主要内容皆包含于官方帮助手册,之所以要拿出来,出于两个原因,手册是英文的+手册是对应2.5.1的。
核心代码如下,注释部分为讲解。 这里只挑干的讲,完整的代码请参考(下载代码)。
//创建一个空白的WorkBook
HSSFWorkbook wb = new HSSFWorkbook();
//基于上面的WorkBook创建属于此WorkBook的Sheet,
//3.0.1版在使用全角Sheet名的时候不必再setEncdoing了,个人感觉方便了许多。
HSSFSheet st = wb.createSheet("测试页");
//创建属于上面Sheet的Row,参数0可以是0~65535之间的任何一个,
//注意,尽管参数是Int类型,但是Excel最多支持65536行
HSSFRow row = st.createRow(0);
//创建属于上面Row的Cell,参数0可以是0~255之间的任何一个,
//同样,是因为Excel最大支持的列数为256列
HSSFCell cell = row.createCell((short) 0);
//设置此单元格的格式为文本,此句可以省略,Excel会自动识别。
//其他还有几种常用的格式,请参考本文底部的补充部分。
cell.setCellType(HSSFCell.CELL_TYPE_STRING);
//此处是3.0.1版的改进之处,上一版可以直接setCellValue("Hello, World!"),
//但是在3.0.1里,被deprecated了。
cell.setCellValue(new HSSFRichTextString("Hello, World!"));
//创建一个文件输出流,指定到C盘根目录下(C盘都有吧?)
//xls是Excel97-2003的标准扩展名,2007是xlsx,目前的POI能直接生产的还是xls格式,
//如果此处把扩展名改成xlsx,在用Excel2007打开此文件时会报错。
FileOutputStream writeFile = new FileOutputStream("c:/helloworld.xls");
//把WorkBook写到流里
wb.write(writeFile);
//记得手动关闭流,官方文档已经做了特别说明,说POI不负责关闭用户打开的流。所以...
writeFile.close();
上面就是创建一个新文档的简易代码,下面的例子是读取刚才创建的Excel并把读取到的内容显示在控制台上。
//指定要读取的文件,本例使用上面生成的helloworld.xls
FileInputStream readFile = new FileInputStream("c:/helloworld.xls");
//创建一个WorkBook,从指定的文件流中创建,即上面指定了的文件流
HSSFWorkbook wb = new HSSFWorkbook(readFile);
//获取名称为“测试页”的sheet
//注意,如果不能确定具体的名称,可以用getSheetAt(int)方法取得Sheet
HSSFSheet st = wb.getSheet("测试页");
//获得第一行,同上,如果此行没有被创建过则抛出异常
HSSFRow row = st.getRow(0);
//获取第一个单元格,如果没有被创建过则抛出异常
HSSFCell cell = row.getCell((short) 0);
//把cell中的内容按字符串方式读取出来,并显示在控制台上
//注意,getRichStringCellValue()方法是3.0.1新追加的,
//老版本中的getStringCellValue()方法被deprecated了
System.out.println(cell.getRichStringCellValue());
//记得关闭流
readFile.close();
上面对创建和读取分别举例说明,回顾两段代码,不难看出POI操作Excel的“套路”:
•获得一个WorkBook(准确说是HSSFWorkBook,对于POI来说,WorkBook是“另有其类”,以下类同)
•获得要读/写的Sheet对象
•获得要操作的Row对象
•获得最小单位——Cell对象
然后就可以随意的读取、写入了。
--------------------------------------------------------------------------------
关于单元格格式的补充:
单元格一共有如下几种格式, 都是HSSFCell类的静态共有属性,
•CELL_TYPE_NUMERIC - 数字格式
•CELL_TYPE_STRING - 字符串(默认)
•CELL_TYPE_FORMULA - 公式
•CELL_TYPE_BLANK - 空白
•CELL_TYPE_BOOLEAN - 布尔
•CELL_TYPE_ERROR - 错误
第二讲 :单元格边框、字体及颜色
此文概要性的讲述了一下单元格的边框、字体以及颜色的设置方式,在POI中,这一切都是通过实例化HSSFCellStyle对象来实现的,HSSFCellStyle类还有很多其他实际有用方法,本例中只是取平时用的比较普遍的一些设置来做演示的。好,开始讲解了……
// 设置行号
row.setHeightInPoints((short) 50);
// 设置列宽,(256 * 50)这种写法是因为width参数单位是单个字符的256分之一
st.setColumnWidth(cell.getCellNum(), (short) (256 * 50));
// 让HSSFWorkbook创建一个单元格样式的对象
// 小技巧:在多处用到完全一样的样式的时候可以用工厂模式生产
HSSFCellStyle cellStyle = wb.createCellStyle();
// 设置单元格的横向和纵向对齐方式,具体参数就不列了,参考HSSFCellStyle
cellStyle.setAlignment(HSSFCellStyle.ALIGN_JUSTIFY);
cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
// 这个地方是用来在单元格里画斜线的
// 原理是在指定的两个点之间画线,然后默认情况此线会随着单元格的变化而变化
// 类似Excel那种设置边框的方式达到的斜线效果目前好像POI不支持
// 如果是我疏忽了请记得告诉我一些,先行谢过啦
HSSFPatriarch patriarch = st.createDrawingPatriarch();
HSSFClientAnchor anchor = new HSSFClientAnchor();
anchor.setAnchor(cell.getCellNum(), row.getRowNum(), 0, 0, (short) (cell.getCellNum() + 1),
row.getRowNum() + 1, 0, 0);
patriarch.createSimpleShape(anchor);
// 设置单元格的文本方式为可多行编写方式
cellStyle.setWrapText(true);
// 设置单元格的填充方式,以及前景颜色和背景颜色
// 三点注意:
// 1.如果需要前景颜色或背景颜色,一定要指定填充方式,两者顺序无所谓;
// 2.如果同时存在前景颜色和背景颜色,前景颜色的设置要写在前面;
// 3.前景颜色不是字体颜色。
cellStyle.setFillPattern(HSSFCellStyle.DIAMONDS);
cellStyle.setFillForegroundColor(HSSFColor.RED.index);
cellStyle.setFillBackgroundColor(HSSFColor.LIGHT_YELLOW.index);
// 设置单元格底部的边框及其样式和颜色
// 这里仅设置了底边边框,左边框、右边框和顶边框同理可设
cellStyle.setBorderBottom(HSSFCellStyle.BORDER_SLANTED_DASH_DOT);
cellStyle.setBottomBorderColor(HSSFColor.DARK_RED.index);
// 创建一个字体对象,因为字体也是单元格格式的一部分,所以从属于HSSFCellStyle
// 下面几个字体的相关设置望文生义,就不用一一说明了吧
HSSFFont font = wb.createFont();
font.setFontName("宋体");
font.setItalic(true);
font.setColor(HSSFColor.BLUE.index);
font.setFontHeightInPoints((short) 20);
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
// 将字体对象赋值给单元格样式对象
cellStyle.setFont(font);
// 将单元格样式对应应用于单元格
cell.setCellStyle(cellStyle);
这样就OK了,可以可以看到效果了。
补充,各个章节的例子最终都在同一个附件内,下载的时候下任何一个页面内的都可以,都是一样的。
Java-Excel报表开发POI—合并、分组及冻结
Java-Excel报表开发POI系列讲座
第三讲 :单元格的合并、数据行的分组以及Excel窗口的冻结
本来想把这三个东西分开来实现的,后来发现分开后内容都很少,于是就合在一起说吧。那总不能干巴巴的列几个例子就完了吧,那就拿比较初级但又会经常遇到的表格类数据的统计的设计来做个小例子。(源码下载)
结果发现——还真够辛苦的。
这次先看效果图吧,其中的竖排并不是真正意义上Excel那种设置的竖排,而是稍微转变了一下输出的方式实现的,因为老外的英文单词没有这种竖排的可能(顶多是旋转,但是那样字体就变了)。除此之外想到的另外一种竖排文字的实现方式就是样式旋转+字体旋转,没测试,不知道是否可用,谁有功夫实现一下,然后记得告诉我结果啊。
老样子,把核心的代码和简要的说明列出来大家看一下吧。
// 这里首先创建一个单元格样式对象,设置了四周的边框以及字体可以换行
// 其中的字体换行是用来竖向显示其中的一个单元格的
// 更好的一点儿做法是再做一个单独的单元格样式对象
// 要不然在处理自动列宽的时候可能会有点儿小问题
HSSFCellStyle normalStyle = wb.createCellStyle();
normalStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
normalStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
normalStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
normalStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
normalStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
normalStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
normalStyle.setWrapText(true);
// 合并单元格A1-C1,填入内容的时候添到第一个格子里就可以
// 但是注意一点:单元格合并后设置边框只在原第一个上有效,
// 如果想应用的合并后的整体,则需要一个个的Create出单元格并应用样式
// 这个明显是一个不太方便的操作,期待POI下一版的改进了
st.addMergedRegion(new Region(0, (short) 0, 0, (short) 2));
HSSFRow row = st.createRow(0);
HSSFCell cell = row.createCell((short) 0);
cell.setCellValue(new HSSFRichTextString("业务一览表"));
cell.setCellStyle(normalStyle);
row.createCell((short) 1).setCellStyle(normalStyle);
row.createCell((short) 2).setCellStyle(normalStyle);
// 设置列头,当然也可以一个一个格子的写,用循环感觉有些取巧而已
// 同样,需要单独给每个单元格应用样式对象
String[] seasonName = { "第一季度", "第二季度", "第三季度", "第四季度" };
for (short i = 3; i < 7; i++)
{
cell = row.createCell(i);
cell.setCellValue(new HSSFRichTextString(seasonName[i - 3]));
cell.setCellStyle(normalStyle);
}
// 这个是竖排文字的实现
// 目前POI没找到(或许没提供,或许我无知)让文字竖排的方法,
// HSSFCellStyle.setRotation()方法是设置旋转角度的,和竖排不太一样,
// 后来想了一下,因为只有中文等全角字符才有竖排的可能,
// 一个英文单词要是竖排看起来恐怕会非常怪异,不过不排除搞艺术的……
st.addMergedRegion(new Region(1, (short) 0, 6, (short) 0));
row = st.createRow(1);
cell = row.createCell((short) 0);
cell.setCellValue(new HSSFRichTextString("地\n区\n代\n理\nA"));
cell.setCellStyle(normalStyle);
for (int i = 2; i < 7; i++)
st.createRow(i).createCell((short) 0).setCellStyle(normalStyle);
// 属于地区的二级分类,竖向合并相邻的两个单元格,其他同上
String[] shopName = { "连锁店A", "连锁店B", "连锁店C" };
for (int i = 1; i < 6; i = i + 2)
{
row = st.createRow(i);
cell = row.createCell((short) 1);
cell.setCellValue(new HSSFRichTextString(shopName[(i - 1) / 2]));
cell.setCellStyle(normalStyle);
st.createRow(i + 1).createCell((short) 1).setCellStyle(normalStyle);
st.addMergedRegion(new Region(i, (short) 1, i + 1, (short) 1));
}
// 属于连锁店的下一级,基本也是创建出来然后赋值+应用样式
for (int i = 1; i < 7; i = i + 2)
{
cell = st.getRow(i).createCell((short) 2);
cell.setCellValue(new HSSFRichTextString("收入"));
cell.setCellStyle(normalStyle);
cell = st.getRow(i + 1).createCell((short) 2);
cell.setCellValue(new HSSFRichTextString("支出"));
cell.setCellStyle(normalStyle);
}
// 数据部分,直接Create然后应用样式,有数据的话这个地方就打数据好了
for (int i = 1; i < 7; i++)
for (short j = 3; j < 7; j++)
st.createRow(i).createCell(j).setCellStyle(normalStyle);
// 冻结Excel的窗口,边界为数据部分的边界
st.createFreezePane(3, 1);
// 按照连锁店级别分组(当然实际情况这样分组没啥意义)
for (int i = 1; i < 7; i = i + 2)
st.groupRow(i, i);
// 按照地区分组
st.groupRow(1, 5);
其实这样实现起来是不是很麻烦呢?答案是:是。
其实这只是举个例子,熟悉一下POI的各种API而已,真正要实现这样一个表格的时候,例如项目需要制作报表等等,通常的做法都是事先把格式一切的东西都手动制作好(这个做好了的文件在实际的项目里我们称之为“数据模板”,简称“模板”),然后在Java应用中适当的时机把这个文件读进来修改,最后再另存到指定的位置或者传递给下一个处理者(例如以流的方式送给Servlet等等),这样其实POI具体做的事情就是向模板里写业务的数据,还是很方便快捷的。
9. php 怎么用post方法获取高德地图poi数据
亲,您点击高德地图PC地图 “开放平台”——点击下角绿色图标“FAQ”——选择对应的问题分类——找到自己遇到的问题——如果答案没有解决您的问题,点击提交“工单”即可
10. 如何通过IP地址进行精准定位
在甲方工作的朋友可能会遇到这样的问题,服务器或者系统经常被扫描,通过IP地址我们只能查到某一个市级城市,如下图:
当我们想具体到街道甚至门牌号,该怎么办???
偶然间发现网络地图有高精度IP定位API的接口,通过该接口我们可以通过IP地址定位到具体的地理位置,甚至能精确到门牌号及周围的标志性建筑。该接口的说明地址为:http://lbsyun..com/index.php?title=webapi/high-acc-ip
若想要使用该接口进行查询,必须先申请一个密钥(AK),如下图:
申请过程就不进行说明了。API的接口参数说明和返回参数说明也不过多的介绍,大家可以看一看。因为我想返回基础定位结果+地址信息+POI信息,所以我将请求参数extensions的值设置为3。
一次完整的http请求为:http://api.map..com/highacciploc/v1?qcip=183.55.116.90&qterm=pc&ak=“你的 密钥(AK)”&coord=bd09ll&extensions=3 。请求结果如下图:
结果为json格式数据:
{"content":{"location":{"lat":23.06588,"lng":115.404586},"locid":"","radius":30,"confidence":0.5,"address_component":{"country":"中国","province":"广东省","city":"汕尾市","district":"海丰县","street":"新平路","street_number":"","admin_area_code":441521},"formatted_address":"广东省汕尾市海丰县新平路","business":"公平"},"result":{"error":161,"loc_time":"2016-10-19 21:53:28"}}
我们需要的字段为:content字段里面的formatted_address。当然我们也可以将location里面的经度和纬度提取出来从而显示在地图上面。有的IP地址会返回pois数据,比如:183.55.116.95。返回参数如下:
{"content":{"location":{"lat":23.082367,"lng":115.466276},"locid":"","radius":30,"confidence":1.0,"address_component":{"country":"中国","province":"广东省","city":"汕尾市","district":"海丰县","street":"S335","street_number":"","admin_area_code":441521},"formatted_address":"广东省汕尾市海丰县S335","pois":[{"name":"双墩村","address":"汕尾市海丰县三三五省道","tag":"行政地标;村庄","location":{"lat":23.082422,"lng":115.465348},"uid":"18010998377147269119"},{"name":"双墩村委会","address":"汕尾市海丰县","tag":"政府机构;各级政府","location":{"lat":23.083394,"lng":115.465914},"uid":"17661602237861855231"},{"name":"长联塘尾","address":"汕尾市海丰县","tag":"行政地标;村庄","location":{"lat":23.081358,"lng":115.467315},"uid":"18010998372852301823"},{"name":"双墩小学","address":"335省道附近","tag":"教育培训;小学","location":{"lat":23.083336,"lng":115.465061},"uid":"17661601958688980991"},{"name":"大溪头","address":"汕尾市海丰县","tag":"行政地标;村庄","location":{"lat":23.090326,"lng":115.465995},"uid":"18010998368557334527"}],"location_description":"双墩村东104米"},"result":{"error":161,"loc_time":"2016-10-19 22:03:31"}}
此时我们可以把pois字段也提取出来,值得注意的是pois为数组,我们可以遍历数组数据。通过上面的分析,用python简单的写了一个脚本,具体代码点击阅读原文可见。
大家把脚本上面的参数ak值改为自己的密钥即可。测试截图如下:
再放一张自己IP的测试截图:
确实精确到了路名,很准确,虽然没有pois的信息。
最后声明一下,成功率:综合定位成功率 65% ,精度:90% 误差 80m 以内;95% 误差 350m。这是官方给出的数据,所说有一定的概率是查询失败的!!!!