Nutz:通过Java代码生成表格图片
效果图:
源码不解释:
private void ResultToJpg(List<Map> list, String title, HttpServletResponse response) { BufferedImage image; int totalrow = list.size(); int totalcol = 7; int imageWidth = 640; int rowheight = 40; int imageHeight = totalrow * rowheight + 105; int startHeight = 20; int startWidth = 10; int colwidth = (int) ((imageWidth - 20) / totalcol); int colwidth2 = (int) ((imageWidth - 20) / (totalcol + 1)); image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB); Graphics2D graphics = (Graphics2D) image.getGraphics(); graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); graphics.setColor(Color.WHITE); graphics.fillRect(0, 0, imageWidth, imageHeight); Font font = new Font("微软雅黑", Font.BOLD, 20); graphics.setFont(font); graphics.setColor(new Color(112, 48, 158)); graphics.drawString(Strings.sNull(title), startWidth, startHeight + 10); font = new Font("微软雅黑", Font.PLAIN, 13); graphics.setColor(new Color(99, 99, 99)); graphics.setFont(font); String subtitle1 = "欢迎访问"; graphics.drawString(subtitle1, startWidth, startHeight + 30); font = new Font("Arial, Helvetica, sans-serif", Font.BOLD, 13); graphics.setColor(new Color(112, 48, 158)); graphics.setFont(font); String subtitle2 = "inm.xuetang.cn"; graphics.drawString(subtitle2, startWidth + 60, startHeight + 30); font = new Font("微软雅黑", Font.PLAIN, 13); graphics.setColor(new Color(99, 99, 99)); graphics.setFont(font); String subtitle3 = "冲榜、制榜!"; graphics.drawString(subtitle3, startWidth + 165, startHeight + 30); //画首行 graphics.setColor(new Color(112, 48, 158)); graphics.fillRect(startWidth, startHeight + rowheight, imageWidth - 20, rowheight); font = new Font("微软雅黑", Font.PLAIN, 12); graphics.setColor(Color.WHITE); graphics.setFont(font); graphics.drawString("#", startWidth + 10, startHeight + rowheight * 2 - 15); graphics.drawString("公众号", startWidth + colwidth - 10, startHeight + rowheight * 2 - 15); //画表头 String[] headCells = {"发布", "总阅读数", " 头条", " 平均 ", "总点赞数", " WCI"}; for (int m = 0; m < headCells.length; m++) { graphics.drawString(headCells[m].toString(), startWidth + colwidth2 * m + colwidth * 2, startHeight + rowheight * 2 - 15); } //画行 for (int j = 0; j < totalrow; j++) { if (j % 2 == 0) { graphics.setColor(new Color(255, 255, 255)); } else { graphics.setColor(new Color(238, 238, 238)); } graphics.fillRect(startWidth, startHeight + (j + 1) * rowheight + 40, imageWidth - 20, startHeight + (j + 1) * rowheight); font = new Font("微软雅黑", Font.BOLD, 12); graphics.setColor(new Color(112, 48, 158)); graphics.setFont(font); graphics.drawString(String.valueOf(j + 1), startWidth + 10, startHeight + (j + 3) * rowheight - 15); Map map = list.get(j); font = new Font("微软雅黑", Font.PLAIN, 12); graphics.setColor(new Color(0, 0, 0)); graphics.setFont(font); graphics.drawString(Strings.sNull(map.get("wx_nickname")), startWidth + (colwidth / 2) - 10, startHeight + (j + 3) * rowheight - 25); graphics.drawString(Strings.sNull(map.get("wx_name")), startWidth + (colwidth / 2) - 10, startHeight + (j + 3) * rowheight - 10); graphics.drawString(Strings.sNull(map.get("url_times")) + "/" + Strings.sNull(map.get("url_num")), startWidth + colwidth2 + colwidth + 10, startHeight + (j + 3) * rowheight - 15); if (NumberUtils.toInt(Strings.sNull(map.get("url_num_10w"))) > 0) { String readnum_all = Strings.sNull(map.get("readnum_all")); int t = NumberUtils.toInt(readnum_all.substring(readnum_all.length() - 4, readnum_all.length() - 3)); if (t > 0) { readnum_all = readnum_all.substring(0, readnum_all.length() - 4) + "." + String.valueOf(t); } else { readnum_all = readnum_all.substring(0, readnum_all.length() - 4); } graphics.drawString(readnum_all + "万+", startWidth + colwidth2 + colwidth * 2 + 5, startHeight + (j + 3) * rowheight - 15); } else { graphics.drawString(Strings.sNull(map.get("readnum_all")), startWidth + colwidth2 + colwidth * 2 + 5, startHeight + (j + 3) * rowheight - 15); } if (NumberUtils.toInt(Strings.sNull(map.get("url_times_readnum"))) > 100000) { String url_times_readnum = Strings.sNull(map.get("url_times_readnum")); int t = NumberUtils.toInt(url_times_readnum.substring(url_times_readnum.length() - 4, url_times_readnum.length() - 3)); if (t > 0) { url_times_readnum = url_times_readnum.substring(0, url_times_readnum.length() - 4) + "." + String.valueOf(t); } else { url_times_readnum = url_times_readnum.substring(0, url_times_readnum.length() - 4); } graphics.drawString(url_times_readnum+"万+", startWidth + colwidth2 + colwidth * 3 - 5, startHeight + (j + 3) * rowheight - 15); } else { graphics.drawString(Strings.sNull(map.get("url_times_readnum")), startWidth + colwidth2 + colwidth * 3 - 5, startHeight + (j + 3) * rowheight - 15); } if (NumberUtils.toInt(Strings.sNull(map.get("readnum_av"))) > 100000) { String readnum_av = Strings.sNull(map.get("readnum_av")); int t = NumberUtils.toInt(readnum_av.substring(readnum_av.length() - 4, readnum_av.length() - 3)); if (t > 0) { readnum_av = readnum_av.substring(0, readnum_av.length() - 4) + "." + String.valueOf(t); } else { readnum_av = readnum_av.substring(0, readnum_av.length() - 4); } graphics.drawString(readnum_av+"万+", startWidth + colwidth2 + colwidth * 4 - 15, startHeight + (j + 3) * rowheight - 15); } else { graphics.drawString(Strings.sNull(map.get("readnum_av")), startWidth + colwidth2 + colwidth * 4 - 15, startHeight + (j + 3) * rowheight - 15); } graphics.drawString(Strings.sNull(map.get("likenum_all")), startWidth + colwidth2 + colwidth * 5 - 20, startHeight + (j + 3) * rowheight - 15); graphics.drawString(Strings.sNull(map.get("wci")), startWidth + colwidth2 + colwidth * 6 - 40, startHeight + (j + 3) * rowheight - 15); } //末行 graphics.setColor(Color.WHITE); graphics.fillRect(startWidth, startHeight + (totalrow + 1) * rowheight + 40, imageWidth - 20, startHeight + (totalrow + 1) * rowheight); try { response.setContentType("image/png"); OutputStream out = response.getOutputStream(); ImageIO.write(image, "png", out); } catch (Exception e) { e.printStackTrace(); } }
微信公众号历史文章回溯:人民日报(2012-12-28至2015-01-15)
人民日报(2012-12-28至2015-01-15).xlsx
链接: http://pan.baidu.com/s/1jG67rXs
密码: flo0
微信:最近开发了个微信弹幕软件
Temp
ComboIocLoader loader = new ComboIocLoader(
new String[]{
“*org.nutz.ioc.loader.json.JsonLoader”, “ioc/”,
“*org.nutz.ioc.loader.annotation.AnnotationIocLoader”, “cn.xuetang”}
);
ioc = new NutIoc(loader);
dao = ioc.get(Dao.class);
Mysql:截取字符串
SELECT SUBSTRING_INDEX(SUBSTRING(url,LOCATE(“sn=”,url)+3),’&’,1),url FROM wx_kw_url_1111
Android:tcpdump抓包命令
adb shell
su
chmod 777 /data/local/tcpdump
/data/local/tcpdump -p -vv -s 0 -w /sdcard/capture.pcap
MySQL:not in 语句优化
select a.*
from wx_nickname a
left join (select distinct nickname_id from wx_group_nickname )b on
a.id = b.nickname_id
where b.nickname_id is null
NutzWk 企业级WEB后台开发框架开源了
NutzWk
https://github.com/Wizzercn/NutzWk
基于Nutz的开源企业级开发框架。
文件编码全部为UTF-8,可以导入Eclispe、IDEA中,jdk7,tomcat 6/7.
创建空的数据库,首次启动项目会自动初始化数据.
本框架已成功应用于XX省交通厅网络问政平台、XX省交通厅CMS内容管理系统、XX公司舆情监测管理中心等项目。
使用条款:
1、个人开源,可以任意修改使用;
2、商业使用,必须更改后台菜单布局、CSS样式、界面颜色等元素(既:不可使用原始界面用于商业项目)。
Cron:表达式在线验证工具
Java 解析Cron表达式,计算执行时间源码:
@At @Ok("raw") public String getCron(@Param("exp") String exp,HttpServletResponse response) { response.setHeader("Content-Type", "text/javascript");//设置跨越访问 $.getScript() List<String> list = new ArrayList<String>(); try { exp= URLDecoder.decode(Strings.sNull(exp),"utf-8"); log.info(exp); CronTriggerImpl cronTriggerImpl = new CronTriggerImpl(); cronTriggerImpl.setCronExpression(exp); Calendar calendar = Calendar.getInstance(); Date now = calendar.getTime(); calendar.add(Calendar.MONTH, 1);//把统计的区间段 List<Date> dates = TriggerUtils.computeFireTimesBetween(cronTriggerImpl, null, now, calendar.getTime());//这个是重点 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); for (int i = 0; i < dates.size(); i++) { if (i > 9) {//这个是提示的日期个数 break; } list.add(dateFormat.format(dates.get(i))); } } catch (Exception e) { } return "var data="+ Json.toJson(list); }
Cordova:Toast浮动提示插件
第一步:编写插件类
package cn.xuetang.plugin; import android.widget.Toast; import org.apache.cordova.CallbackContext; import org.apache.cordova.CordovaInterface; import org.apache.cordova.CordovaPlugin; import org.json.JSONArray; import org.json.JSONException; /** * Created by Wizzer on 14-8-28. */ public class ToastPlugin extends CordovaPlugin { public ToastPlugin() { } public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { if (this.cordova.getActivity().isFinishing()) return true; if (action.equals("show")) { this.show(args.getString(0)); } else if (action.equals("showlong")) { this.showlong(args.getString(0)); } else { return false; } callbackContext.success(); return true; } public void show(String message) { Toast.makeText(this.cordova.getActivity(), Toast.LENGTH_SHORT).show(); } public void showlong(String message) { Toast.makeText(this.cordova.getActivity(), message, Toast.LENGTH_LONG).show(); } }
第二步:配置 res/xml/config.xml
<feature name="ToastPlugin"> <param name="android-package" value="cn.xuetang.plugin.ToastPlugin" /> </feature>
注:这里的 feature name ,要和↓↓面讲的的js文件里一致。
第三步:创建js文件 plugins/toast.js
/** * Created by Wizzer on 14-8-28. */ cordova.define("cn.xuetang.plugin.ToastPlugin", function(require, exports, module) { var exec = require('cordova/exec'); module.exports = { /** * 一共5个参数 第一个 :成功回调 第二个 :失败回调 第三个 :将要调用的类的配置名字(在config.xml中配置↑↑) 第四个 :调用的方法名(一个类里可能有多个方法 靠这个参数区分) 第五个 :传递的参数 以json的格式 */ show: function(message) { exec(null, null, "ToastPlugin", "show", [message]); }, showlong: function(message) { exec(null, null, "ToastPlugin", "showlong", [message]); } }; });
注:js里两个方法,分别对应类中的两个方法
第四步:修改 cordova_plugins.js 引用 tocas.js
在 module.exports = [ ] 中追加如下代码:
{ "file": "plugins/toast.js", "id": "cn.xuetang.plugin.ToastPlugin", "merges": [ "navigator.toast" ] }
最后:调用
navigator.toast.show("再点击一次退出"); navigator.toast.showlong("再点击一次退出");
Cordova:连续按两次返回键退出程序
/** * Created by Wizzer on 14-8-28. */ var num = 0; var login = { initialize: function () { this.bindEvents(); }, bindEvents: function () { document.addEventListener('backbutton', this.eventBackButton, false); }, eventBackButton: function () { num++; if (num > 1) { navigator.app.exitApp(); } navigator.toast.show("再点击一次退出"); // 3秒后重新计数 var intervalID = window.setInterval(function() { num=0; window.clearInterval(intervalID); }, 3000); } };
浮动提示插件见:
/?p=3026
Java:乱码字符不能插入MySQL的解决办法
.replaceAll(“[^a-zA-Z_\u4e00-\u9fa5]”, “”)
只剩下中文和英文字母了,悲催。
Caused by: java.sql.SQLException: Incorrect string value: ‘\xF0\x9F\x98\xB7’ for column ‘description’
Nutz:代码生成器开源了
项目地址: https://github.com/Wizzercn/NutzCodematic
Nutz 代码生成器:
可以生成Pojo类、Action类;
支持MySQL、Oracle、MS SQL2000、ODBC等;
classes是在jdk1.7下编译,可以直接双击 run.bat 运行。
迟迟没放出来的原因是代码写的太烂……
关于帝国CMS和PHPCMS的开发对比
使用帝国CMS,花了近一个月时间开发了一个网站,开发完成后客户对后台非常不满意,决定换成PHPCMS找人重做。- –
怎么说呢,帝国CMS开发起来比较灵活,可是弊端也很多,比如模板、标签、自定义SQL、自定义列表、模型等等,
做起来是相当的麻烦,从这里转到那里,又要自定义函数又要这个那的,,否则怎么会要花近一个月时间做个网站呢?
做网站真的应该是分分钟的事情,而帝国CMS让我花费了超过1/3时间在折腾自定义标签、函数等,边学习边研究边开发。
我不清楚PHPCMS开发要多久,另外那个人说一周加班加点可以搞定。
帝国CMS最人命的是,不光对开发人员不友好,对网站编辑人员更加不友好,,各种麻烦,各种功能不支持,
对不之下,PHPCMS编辑网站起来方便多了,可以裁剪标题图不变形、可以推送文章到广告位等等。
一直是从事JAVA开发的,PHP的CMS也就接触过Wordpress而已,,如果不是老板确定用帝国CMS,
如果不是自己看中帝国自带的商城,打死也不会选择帝国CMS。。。。
难怪官方都不再更新维护了,,体验不是一般的烂,算是浪费时间换得了个教训,望后者不要付后尘。
JAVA:网易微博模拟登陆
网易微博登陆验证,第一次请求使用BASE64加密、第二次请求使用MD5+RSA加密,比较变态,于是使用JAVA+JS相结合的方式,调用其JS方法得到加密字符串。
/core1.7.0.js 是经过处理的,删掉几行在JAVA引用中会报错的浏览器对象。
import org.apache.http.HttpResponse; import org.apache.http.client.CookieStore; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.velocity.util.StringUtils; import org.nutz.lang.Files; import org.nutz.lang.util.ClassTools; import org.nutz.repo.Base64; import javax.script.Invocable; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; /** * Created by Wizzer on 14-7-7. */ public class Netease { static String index_url = "http://t.163.com/session"; static String login1_url = "http://reg.163.com/services/httpLoginExchgKeyNew"; static String login2_url = "http://reg.163.com/httpLoginVerifyNew.jsp"; static String status_url = "http://t.163.com/share/check/status"; UrlUtil urlUtil = new UrlUtil(); public static void main(String[] args) { CookieStore cookieStore = new Netease().login("email", "password"); } public CookieStore login(String userid, String password) { try { DefaultHttpClient client = new DefaultHttpClient(); HttpGet get = new HttpGet(login1_url + "?rnd=" + Base64.encodeToString(userid.getBytes(), true) + "&jsonp=setLoginStatus"); get.setHeader("Accept", "*/*"); get.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36"); HttpResponse response = client.execute(get); int code = response.getStatusLine().getStatusCode(); if (code == 200) { InputStream in = response.getEntity().getContent(); BufferedReader reader = new BufferedReader(new InputStreamReader(in)); String line = "", res = ""; while (null != (line = reader.readLine())) { res += line; } System.out.println("res:::" + res); if (res.contains("200")) { String[] str = StringUtils.split(urlUtil.getStr(res, "setLoginStatus(\"", "\")"), "\\n"); String o = str[1], h = str[2]; ScriptEngineManager sem = new ScriptEngineManager(); ScriptEngine se = sem.getEngineByName("javascript"); se.eval(getJs()); String jiami = ""; if (se instanceof Invocable) { Invocable invoke = (Invocable) se; jiami = invoke.invokeFunction("getCode", password, o, h).toString(); System.out.println("jiami = " + jiami); } DefaultHttpClient client2 = new DefaultHttpClient(); client2.setCookieStore(client.getCookieStore()); HttpGet get2 = new HttpGet(login2_url + "?rcode=" + jiami + "&product=t&jsonp=setLoginStatus&savelogin=0&username=" + userid); get2.setHeader("Accept", "*/*"); get2.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36"); HttpResponse response2 = client2.execute(get2); int code2 = response2.getStatusLine().getStatusCode(); if (code2 == 200) { InputStream in2 = response2.getEntity().getContent(); BufferedReader reader2 = new BufferedReader(new InputStreamReader(in2)); String line2 = "", res2 = ""; while (null != (line2 = reader2.readLine())) { res2 += line2; } System.out.println("res2:::" + res2); if (res.contains("200")) { return client2.getCookieStore(); } } } } return null; } catch (Exception e) { e.printStackTrace(); return null; } } private String getJs() { String jscontent = Files.read(ClassTools.getClassLoader().getResource("").getPath() + "netease" + "/core1.7.0.js"); jscontent += "function getCode(p,o,h){\n" + "\t\t\t\tvar l=new RSAKey();\n" + "\t\t\t\tl.setPublic(h,o);\n" + "\t\t\t\treturn l.encrypt(getMd5(p));\t\t\t\t\n" + " }"; return jscontent; } }
原创:帝国CMS7.0批量上传图片集插件
版本特点:
1、使用系统自带的水印系统,勾选即可使用;
2、可勾选生成缩略图。
使用方法:
1、将 uploadify 文件夹解压至 ../e/extend/
2、系统–>数据表与系统模型–>管理数据表–>图片系统数据表–>管理字段–> morepic 修改:
将“输入表单替换html代码.html”文件内容,拷贝替换掉“输入表单替换html代码”
3、搞定。
ps:uploadify.php 第49行,没有用到的,可以删掉提高效率。
下载地址:
1、原版下载(或附件):http://pan.baidu.com/s/1kTDmdyZ
2、上传时获取照片附加属性(曝光、光圈、相机型号等)版本:
http://pan.baidu.com/s/1qWuLahQ
CSS:限制图片最大宽度
img{max-width:800px;width:expression(this.width > 800 ? 800: true);height:auto;}
Nutz:下载文件(输出文件)
HSSFWorkbook wb = new HSSFWorkbook();
OutputStream out = new FileOutputStream(“x.xls”);
wb.write(out);
out.close();
return new File(“x.xls”);
ByteArrayOutputStream out = new ……..;
wb………
out.close();
ByteArrayInputStream in = new ………..(out.toByte…);
return in;