转载自 Java制作VCARD
简介:
vCard是电子名片的文件格式标准。它一般附加在电子邮件之后,但也可以用于其它场合(如在互联网上相互交换)。vCard可包含的信息有:姓名、地址资讯、电话号码、URL,logo,相片等。
——摘自维基百科https://zh.wikipedia.org/wiki/VCard
vCard规范容许公开交换个人数据交换 (Personal Data Interchange PDI) 信息,在传统纸质商业名片可找到这些信息。规范定义电子名片(或叫vCard)的格式。 vCard 规范可作为各种应用或系统之间的交换格式。定义的格式与传送的方法无关。传送交换可能是文件系统,点对点交换的公共电话网络,以有线网络或无线传送的方式。用户能在互联网上直接利用vCard。电子邮件能转发在vCard中人信息。网页上很多用户填写的表格可自动使用vCard。
——摘自百度百科http://baike.baidu.com/view/495045.htm
以上就是关于vCard的基本介绍,维基百科(英文)https://en.wikipedia.org/wiki/VCard写的比较全,可惜我看不懂。关于vCard格式介绍的文章网上也有很多,我就不再一一阐述。但是关于Java操作vCard的例子却不是很多了,有些也就是自己单单写的一个解析类,于是我漫游网络,最终找到了ez-vcard,我不知道还有没有别的库能操作vCard的,肯定有,但是我也懒得去找了,反正这个可以用就行了。╮( ̄▽ ̄)╭
ez-vcard:
github主页:https://github.com/mangstadt/ez-vcard
下载地址:https://github.com/mangstadt/ez-vcard/wiki/Downloads
API文档:http://mangstadt.github.io/ez-vcard/javadocs/latest/index.html
参考资料:https://github.com/mangstadt/ez-vcard/wiki
Maven
com.googlecode.ez-vcard
ez-vcard
...
Gradle
compile 'com.googlecode.ez-vcard:ez-vcard:0.9.11'
ez-vcard可以操作vCard、xCard、jCard、hCard,在这里,我主要介绍vCard的写操作。
我们首先新建一个项目,我这里使用的是Intellij IDEA创建的Mavenx项目,如果不是Maven项目,也可以直接导入jar包使用
新建vacrd.properties用于模拟数据
vcard.name=张三
vcard.address=湖北武汉
[email protected]
vcard.mobile=182****2658
vcard.phone=027-49***44
vcard.fax=49**46
vcard.org=武汉家里蹲股份有限公司
vcard.role=软件开发员
vcard.title=投研产品事业部
vcard.url=http://www.whjld.com/san.zhang
vcard.qq=32*****44
vcard.weixin=zhangsan
vcard.weibo=http://weibo.com/zhangsan
新建VCardUtil.java
编写getProperties()方法用于读取资源文件
/** * 读取资源文件 * @return Properties */ public Properties getProperties(){ //读取资源文件 InputStream resourceAsStream = this.getClass().getClassLoader() .getResourceAsStream("vcard.properties"); Properties properties = new Properties(); try { //使用字符流,防止中文乱码 BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(resourceAsStream,"UTF-8")); properties.load(bufferedReader); } catch (IOException e) { e.printStackTrace(); } return properties; }
然后开始编写createVCard(Properties);
首先new一个VCard实体类
VCard vcard = new VCard();
以Email为例,添加属性
新建email,添加内容
Email email = new Email(properties.getProperty("vcard.email"));
添加Email的类别为INTERNET,关于类别,可以去查看vCard规范
email.getTypes().add(EmailType.INTERNET);
当添加多个邮箱后,可以设置优先级
email.setPref(1);
有关属性设置完后,将属性添加进vCard中
vcard.addEmail(email);
其他属性基本类似,具体可以查看官方API,值得一提的是PHOTO使用的是图片的base64,我们可以直接使用以下方式进行添加
Photo photo = new Photo(new File("D://photo.jpg"), ImageType.JPEG);
关于自定义属性
VCardProperty QQ = new RawProperty("X-QQ", properties.getProperty("vcard.qq")); vcard.addProperty(QQ);
所有属性添加完成后,编写main方法
public static void main(String[] args) { VCardUtil vCardUtil = new VCardUtil(); VCard vCard = vCardUtil.createVCard(vCardUtil.getProperties()); String s = Ezvcard.write(vCard).version(VCardVersion.V4_0).go(); System.out.println(s); }
设置vCard的版本号为4.0,运行结果如下
BEGIN:VCARD
VERSION:4.0
PRODID:ez-vcard 0.9.11
N:;张三;;;
FN:张三
ADR;TYPE=dom;TZ=UTC+8:;;湖北武汉;;;;
EMAIL;TYPE=internet;PREF=1: [email protected]
TEL;TYPE=cell:182****2658
TEL;TYPE=work:027-49***44
TEL;TYPE=fax:49**46
ORG:武汉家里蹲股份有限公司
ROLE:软件开发员
TITLE:投研产品事业部
URL:http://www.whjld.com/san.zhang
X-QQ:32*****44
X-WEIXIN:zhangsan
X-WEIBO:http://weibo.com/zhangsan
END:VCARD
上面没有添加PTOTO,如果添加了PHOTO,你会发现一件奇怪的事,代码一行过长后会自动换行,并且在第二行会加一个空格,导致文件不能正常使用(如果你们可以正常使用,当我没说)。
BEGIN:VCARD
VERSION:4.0
PRODID:ez-vcard 0.9.11
N:;张三;;;
FN:张三
ADR;TYPE=dom;TZ=UTC+8:;;湖北武汉;;;;
EMAIL;TYPE=internet;PREF=1: [email protected]
TEL;TYPE=cell:182****2658
TEL;TYPE=work:027-49***44
TEL;TYPE=fax:49**46
ORG:武汉家里蹲股份有限公司
ROLE:软件开发员
TITLE:投研产品事业部
PHOTO:data:image/jpeg;base64,/9j/4RR6RXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEAAA
EaAAUAAAABAAAAYgEbAAUAAAABAAAAagEoAAMAAAABAAIAAAExAAIAAAAcAAAAcgEyAAIAAAAU
AAAAjodpAAQAAAABAAAApAAAANAADqYAAAAnEAAOpgAAACcQQWRvYmUgUGhvdG9zaG9wIENTNS
BXaW5kb3dzADIwMTY6MDQ6MDggMTA6MTQ6MDUAAAAAA6ABAAMAAAAB//8AAKACAAQAAAABAAAE
AKADAAQAAAABAAADAAAAAAAAAAAGAQMAAwAAAAEABgAAARoABQAAAAEAAAEeARsABQAAAAEAAA
EmASgAAwAAAAEAAgAAAgEABAAAAAEAAAEuAgIABAAAAAEAABNEAAAAAAAAAEgAAAABAAAASAAA
AAH/2P/tAAxBZG9iZV9DTQAC/+4ADkFkb2JlAGSAAAAAAf/bAIQADAgICAkIDAkJDBELCgsRFQ
8MDA8VGBMTFRMTGBEMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAENCwsNDg0Q
Dg4QFA4ODhQUDg4ODhQRDAwMDAwREQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA
wM/8AAEQgAeACgAwEiAAIRAQMRAf/dAAQACv/EAT8AAAEFAQEBAQEBAAAAAAAAAAMAAQIEBQYH
CAkKCwEAAQUBAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAABBAEDAgQCBQcGCAUDDDMBAAIRAw
QhEjEFQVFhEyJxgTIGFJGhsUIjJBVSwWIzNHKC0UMHJZJT8OHxY3M1FqKygyZEk1RkRcKjdDYX
0lXiZfKzhMPTdePzRieUpIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm9jdHV2d3h5ent8fX5/cRAA
ICAQIEBAMEBQYHBwYFNQEAAhEDITESBEFRYXEiEwUygZEUobFCI8FS0fAzJGLhcoKSQ1MVY3M0
.
.
.
//代码太长,只截取一部分
查阅API之后,发现他有专门的 Writer方法,并且可以设置每行的长度,Writer方法可以写到OutputStream、Writer、File里面,更具情况可以自行选择。
添加getStringVCard() 测试
/** * 获取字符串形式的vcard * @param vCard vcard * @return */ public String getStringVCard(VCard vCard){ CharArrayWriter charArrayWriter = new CharArrayWriter(); VCardWriter vCardWriter = null; try { //定义vcard输出流 vCardWriter = new VCardWriter(charArrayWriter,VCardVersion.V3_0); //设置每行的长度,null为不限制 vCardWriter.getRawWriter().getFoldedLineWriter().setLineLength(null); //讲vCard写到输出流里面 vCardWriter.write(vCard); } catch (IOException e) { e.printStackTrace(); }finally { if (vCardWriter != null) try { vCardWriter.close(); } catch (IOException e) { e.printStackTrace(); } } return charArrayWriter.toString(); }
官方也给出了输出到File的例子,和一些设置信息
Example:
VCard vcard1 = ... VCard vcard2 = ... File file = new File("vcard.vcf"); VCardWriter writer = null; try { writer = new VCardWriter(file, VCardVersion.V3_0); writer.write(vcard1); writer.write(vcard2); } finally { if (writer != null) writer.close(); } Changing the line folding settings: VCardWriter writer = new VCardWriter(...);//disable line folding writer.getRawWriter().getFoldedLineWriter().setLineLength(null);//change line length writer.getRawWriter().getFoldedLineWriter().setLineLength(50);//change folded line indent string writer.getRawWriter().getFoldedLineWriter().setIndent("/t");//change newline character writer.getRawWriter().getFoldedLineWriter().setNewline("**");后记:
目前可能部分手机不支持4.0格式的vCard,比如猴米就只支持3.0格式的
小米手机关于3.0版本头像支持问题
3.0版本的PHOTO格式为:
PHOTO;ENCODING=b;TYPE=jpeg:……
维基百科上写的也是ENCODING=b
华为,苹果的都可以正常显示,但是小米手机显示不了头像,改成ENCODING=BASE64,就可以显示了,可能是小米的解析的问题