GNotes随笔记导出文件保存到数据库
gnotes随笔记导出文件转换并保存到数据库/json文件
文章目录
前言
因为随笔记官方现在免费版不能自动同步笔记信息了,只有vip才有同步的功能,而且图片也只支持压缩图了。但是我在随笔记上已经记录了很多笔记,迁移也不方便,而且笔记没有保存到自己手上始终不太放心,于是就想着能不能将随笔记我的笔记信息都保存下来。
一、如何获取gnote随笔记的笔记信息
gnote官方提供了导入/导出功能,安卓版的gnote随笔记app内的设置->导入/导出->就能立即导出到手机sd卡(或内置储存)上。
但是导出的文件都是html格式的,当网页打开查看倒是没有问题,但是要统一整理就不是很方便了。
随笔记导出的html文件都是靠a标签跳转的,仅仅支持查看,要想搜索或者其他操作就不支持了。
二、整体流程
1.流程非常简单,因为考虑到后期使用springBoot来管理笔记内容,所以使用的是java的解析方式
二、读取解析导出的html文件
今天这篇主要是将的如何读取解析随笔记导出的html文件
1.首先打开一个html文件
导出文件
导出示例文件(html示例):
<!-- 前面省略 -->
<input name="X-Folder-Name" type="hidden" value="分类"/>
<input name="X-Reminder-Date" type="hidden" value="0"/>
<input name="X-Starred" type="hidden" value="false"/>
<div class="wrap">
<div id="header">
<a href="../notes.html" onClick="window.GoBack.goBack(); ">返回
<strong></strong><span></span>
</a>
<h4 class="text_overflow">标题</h4>
</div>
<div class="content">
<p class="create_time">创建时间: 2013/2/12 18:06<br>修改时间: 2013/2/13 16:14</p>
<p class="note_content">笔记内容 <br>第二行笔记内容... </p>
<div style="width: 100%; max-width: 800px; margin: 0 auto; text-align:center;">
<a href="a9a4ad48602d46978fea24e36362975c_IMG_20130119_115809.jpg">
<img class="image" src="a9a4ad48602d46978fea24e36362975c_IMG_20130119_115809.jpg" style="max-width: 800px;" width="85%"/>
</a>
</div>
</div>
</div>
</body>
</html>
导出的html基本上就是这样一个模板
建立笔记模型
笔记html文件里的信息大概就是这几个:标题、类型、创建/修改时间、笔记内容、图片
所以据此可以建立笔记实体类和表结构:
@Data
@ToString
public class Gnote {
private String id; // id
private String title; // 标题
private String type; // 类型
private Date createTime; // 创建时间
private Date updateTime; // 修改时间
private String noteContent; // 笔记内容
private String html; // 笔记内容原始html(可不要)
private String imageBase64List; // 图片base64编码列表或是返回的oos地址
private String userId; // 关联用户名
}
因为是根据表结构生成的实体类,注释不太规范
CREATE TABLE `g_note` (
`id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '主键id',
`title` varchar(512) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '标题',
`type` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '类型',
`create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
`update_time` datetime(0) NULL DEFAULT NULL COMMENT '修改时间',
`note_content` varchar(4000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '笔记内容',
`html` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '笔记内容原始html',
`image_base64_list` blob NULL DEFAULT NULL COMMENT '图片base64编码列表或是返回的oos地址',
`user_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '关联用户名',
PRIMARY KEY (`id`) USING BTREE,
INDEX `笔记索引`(`title`, `type`, `update_time`, `user_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = 'gnote笔记信息' ROW_FORMAT = Dynamic;
解析html文件
因为导出的html的标签元素都是相同的,所以可以通过解析html来获取对应的信息还是扫描文件夹获取所有html文件
扫描文件夹
/**
* 扫描文件夹
*
* @param dir
*/
private List<File> scanDir(String dir, Boolean getDir) {
File dirFile = new File(dir);
List<File> jsonArray = new ArrayList<File>();
if (dirFile.exists() && dirFile.isDirectory()) {
File[] tempList = dirFile.listFiles();
for (int i = 0; i < tempList.length; i++) {
if (tempList[i].isFile() && tempList[i].getName().contains(".")) {
String lastName = tempList[i].getName().substring(tempList[i].getName().lastIndexOf("."), tempList[i].getName().length());
if (!getDir && ".html".equals(lastName.toLowerCase())) {
jsonArray.add(tempList[i]);
}
}
if (tempList[i].isDirectory()) {
//这里就不递归了,
if (getDir) {
jsonArray.add(tempList[i]);
}
}
}
}
// logger.info(jsonArray.toString());
return jsonArray;
}
读取html文件内容
/**
* 读取文本文件
*
* @param file 文件
* @return
*/
public static String readTextFile(File file) {
return readTextFile(file, "UTF-8");
}
/**
* 读取文本文件
*
* @param file 文件
* @param charsetName 编码
* @return
*/
public static String readTextFile(File file, String charsetName) {
//找到文件,读取文件
BufferedReader bufferedReader1 = null;
StringBuffer content = new StringBuffer();
try {
bufferedReader1 = new BufferedReader(new InputStreamReader(new FileInputStream(file), charsetName));
String line = null;
while ((line = bufferedReader1.readLine()) != null) {
content.append(line).append(System.getProperties().getProperty("lineSeparator"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bufferedReader1 != null) {
try {
bufferedReader1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return content.toString();
}
解析html文件内容
/**
* Jsoup解析html
*
* @param file
* @return
*/
private Gnote getNotes(File file) {
Gnote gnote = new Gnote();
String text = readTextFile(file);
try {
//解析为Document对象
Document document = Jsoup.parse(text);
if (document != null) {
//获取标题
Elements el1 = document.select("#header .text_overflow");
String title = el1.first().text();
gnote.setTitle(title);
String type = this.getFirstElement(document, "input[name='X-Folder-Name']").val();
if (null == type || "".equals(type)) {
type = "allType";
}
gnote.setType(type);
//获取并解析时间信息
String time = this.getFirstElement(document, ".content .create_time").text();
String text1 = "创建时间: ";
String text2 = " 修改时间: ";
String createTime = time.substring(text1.length(), time.indexOf(text2));
String updateTime = time.substring(time.indexOf(text2) + text2.length(), time.length());
gnote.setCreateTime(sdf1.parse(createTime));
gnote.setUpdateTime(sdf1.parse(updateTime));
//获取笔记内容信息
Element contentElement = this.getFirstElement(document, ".content .note_content");
gnote.setHtml(contentElement.html());
gnote.setNoteContent(contentElement.text());
gnote.setUserId(userId);
//获取图片
JSONArray imagesJsonArray = new JSONArray();
Elements images = document.select(".content div img");
if (null != images && images.size() > 0) {
for (Element image : images) {
String src = image.attr("src");
File imageFile = new File(file.getParent() + "/" + src);
if (imageFile.exists()) {
//图片存在了
String imageInfo = this.getImageInfo(imageFile);
imagesJsonArray.add(imageInfo);
}
}
}
if (imagesJsonArray.size() > 0) {
gnote.setImageBase64List(imagesJsonArray.toString());
}
gnote.setId(UUID.fastUUID().toString(true));
}
} catch (Exception e) {
e.printStackTrace();
}
return gnote;
}
/**
* 获取第一个元素
*
* @param document
* @param cssQuery
* @return
*/
private Element getFirstElement(Document document, String cssQuery) {
return document.select(cssQuery).first();
}
解析规则都是根据示例html进行解析的,Jsoup的解析规则和jQuery一毛一样,只要你会一点点前端和jQuery,那么解析就没什么问题。解析步骤基本上都在注释中写了
保存Gnote文件
如果是要保存到数据库,那么直接写sql去insert就行了:
/**
* 写入数据库
*
* @param gnoteList
* @return
*/
private int writeToDataBase(List<Gnote> gnoteList) {
int index = 0;
//先清除原来的信息 不需要的可以屏蔽
staticDateBaseConnUtil.edit("delete from g_note", true);
//遍历插入
for (Gnote gnote : gnoteList) {
//方法的update不会自动提交,遍历多了会抛异常
index += staticDateBaseConnUtil.edit("insert into g_note(id, title, type, create_time, update_time, note_content, html, image_base64_list, user_id)" +
"values(?,?,?,?,?,?,?,?,?)", true,
gnote.getId(), gnote.getTitle(), gnote.getType(), gnote.getCreateTime(), gnote.getUpdateTime(), gnote.getNoteContent(), gnote.getHtml(), gnote.getImageBase64List(), gnote.getUserId());
}
return index;
}
如果是要保存到json,那么直接转json并写入到文件就行了:
/**
* 写入文件
*
* @param gnoteList
* @return
*/
private int writeToJsonFile(List<Gnote> gnoteList) {
JSONArray jsonArray = JSONArray.fromObject(gnoteList);
String json = jsonArray.toString();
writeTextFile(new File("保存的地址"), json);
return gnoteList.size();
}
/**
* 写入文本文件
*
* @param file 文件
* @param text 内容
*/
public static void writeTextFile(File file, String text) {
writeTextFile(file, text, "UTF-8");
}
/**
* 写入文本文件
*
* @param file 文件
* @param text 内容
* @param charsetName 编码
*/
public static void writeTextFile(File file, String text, String charsetName) {
//写入文件
file.delete();
BufferedWriter writer = null;
try {
file.createNewFile();
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), charsetName));
writer.write(text);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
还有图片转base64或者oos上传的就不详述了,有需要后面再补充吧
总结
基本上完整的解析流程大概就是这样了,如果还有不清楚的或是想直接用的;可以直接先拉下面的完整示例项目来看看。
后记
后面要是有空讲一下用springBoot+uniApp来自己管理导出的笔记文件吧,当然功能还很简陋;其实这主要是给gnote笔记备个份和以后转到其他笔记做准备的。
完整的示例项目源码地址: https://gitee.com/anlinxi/gnoteReaderDemo
后记:因为有些不懂代码的童鞋也想使用该功能,所以我做了个页面解析gnote导出的zip文件供大家使用: gnote导出文件解析excel下载
若是笔记里有敏感或重要信息的,还是使用上面的源码自己本地解析吧。