Dataviewjs的奇技淫巧

不是这样的:rofl:,我说的加载好是指代码中的数据,因为像我以前写的代码中渲染代码之间会有异步运行的代码(参照上面的两段代码),我猜是这个打断了pdf的导出,所以说如果dataviewjs的渲染结果导出pdf有问题的话,应该要对代码进行修改,一般的dataviewjs直接导出应该是没有问题的

请教大佬:如何提取出指定文件夹下所有文档中由某个callout类型(如> [!note])包裹的内容,自动汇总在一个页面,请问如何用代码实现呀?

那一般用户很难解决这个问题啊,摊手

一般用户也不会玩得这么花啊,一般代码导出结果不是正常的吗(我不怎么用导出)

dv命令基本上都能正常导出,但dvjs很多都没法导出,或导出内容不完整。导出去主要是分享给别人,我还挺常用的

不对啊,我测过了,大部分简单的dvjs还是可以正常导出的

```dataviewjs
let files = dv.pages(`"300-系列笔记/310-课程/模拟电路"`)
let keyword = 'tip'
for(let i of files) {
	let content = await app.vault.readRaw(i.file.path)
	content = content.split('\n')
	let index = content.map((p,i)=>{if(p.startsWith(`>[!${keyword}]`))return i})
	let callout = index.map(p=>{
		let t = ''
		while(content[p]?.startsWith('>')) t+=content[p++]+'\n'
		return t
	})
	dv.paragraph('### '+i.file.link)
	dv.paragraph(callout.map(p=>p+='\n\n'))
}
```

感谢大佬!!! :smiling_face:

是的,简单的js,是能导出来。不过您教我的那个js命令,就没办法完整导出来。

是啊,那这一段不就解决了这个问题

1 个赞

@lazyloong 大佬,这段代码【根据小标题汇总内容】,我想新增2个功能:1、按文件名筛选;2、当结果为空时,不显示出来,请问应该怎样做呢?

```dataviewjs
// 表格标题内容
const headers = ["路径", "内容"];

// 需要索引的栏目
const targetHeading = "{{VALUE:请输入小标题名称}}";

// 用于定位的标签或者文件夹地址
const pages = dv.pages('"文件夹A" or "文件夹B"');
const pagesArray = pages.array();
const targetPagesArray = [];
const contentArray = [];

for(let i = 0; i < pagesArray.length;i++) {
    const currentFile = pagesArray[i].file;
    const sectionCache = app.metadataCache.getFileCache(currentFile);
    
    const headingCache = sectionCache.headings?.filter(h => {
        return h.heading === targetHeading
    })
    
    if(headingCache?.length > 0) {
        const headingRange = {
            start: headingCache[0].position.start.offset,
            end: headingCache[0].position.end.offset,
        };
        const heading = headingCache[0].heading;
        const content = await dv.io.load(currentFile.path);
        
        if(!content) continue;
        const headingInRange = content.slice(headingRange.start, headingRange.end);
        const contentInNextRange = content.slice(headingRange.end);
        
        const level = headingInRange.match(/#{1,6}/)[0].length;
        const nextHeadingRegex = new RegExp(`(^|\\n)#{1,${level}}\\s`);
        
        const position = contentInNextRange.match(nextHeadingRegex);

        let contentRange;
        let positionEnd;

        if(position) {
            positionEnd = headingRange.end + position?.index;
            contentRange = content.slice(headingRange.end, positionEnd);
        }else {
            contentRange = content.slice(headingRange.end);
        }
        
        const link = dv.sectionLink(currentFile.name, targetHeading)
        contentArray.push({
            file: link,
            content: contentRange,
        })
    }
}

dv.table(headers, contentArray.map(
    p => 
        [
            p.file,
            p.content,
        ]
    
))

自问自答,关于按文件名筛选,已解决。供大家参考

const pages = dv.pages(‘“文件夹A” or “文件夹B”’).filter(p => p.file.name.includes(“A”)).filter(p => p.file.name.includes(“B”)).sort(p=>p.file.mtime,“desc”);

楼主打扰了,可以问一下如何实现筛选出距创建时间指定天数的文件么,看了好多贴子都只有今天到指定天数的,没有办法排除掉中间的文件,自己试了好多但是筛选出来都是0

这样看行不行

```dataviewjs
let difference = 2
dv.list(dv.pages().values.filter(p=>moment().diff(moment(Number(p.file.cday)),'day')==difference).map(p=>p.file.link))
```
1 个赞

谢谢您!是可以的!

想问一下,我想根据某个文件夹下面的文件里的一个字段进行分组,并统计数量,这个怎么实现?
好像没有count这个功能

table 字段名称,count(字段名称)
from "500_日记" 
where date(file.name) >= date(today) - dur(30 day)
sort file.name desc
group by 字段名称

count换成length

不太对呢,length的结果返回的是字段值字符串的长度

啊,这样吗,我看文档还以为是列表的长度呢,那我就不晓得了,我对dataview不太熟悉

摸索了一下,目前只能用paragraph展示,想用table展示出来,语法现在没摸索清楚,求教。
功能是 先获取指定文件夹里的每个文件中的字段值,统计每个值出现的次数,以table的方式进行展示,并根据次数进行降序排列。

let files = dv.pages(`"500_日记"`)
for (let group of files.groupBy(p => p["地点"])) {
	dv.paragraph(group.key + "  " + group.rows.length);
}