获取文本,按句整理
在客户端展示PDF view之后,我们需要获取到PDF内的文本,并将它们重新组合/分割。
实际上我们获得的是一个PDF上每个文字的点位transform,我们通过这个字段来判断文字是否在同一行,并且将它们收集在一起处理。
处理方法
客户端
const getLongContentFromPage = (pageContentCollection: PageContentCollection) => {
const endRegs = /[\.\!!。]/
let longContextList: Array<LONG_CONTEXT_TYPE> = []
_.map(pageContentCollection, pageContent => {
const { page, contentList } = pageContent || {}
let longContext: LONG_CONTEXT_TYPE = {
page,
textlines: [],
}
let thisLine = '',
lastTransformString = ''
_.map(contentList, (content, contentIndex: number) => {
const { transform, str } = content || {}
const sameLineTrans = transform
.slice(0, 4)
.concat([transform[transform.length - 1]])
.join(',')
if (!lastTransformString || sameLineTrans == lastTransformString) {
thisLine += str
if (contentIndex == contentList.length - 1) {
longContext.textlines.push(thisLine)
}
} else {
longContext.textlines.push(thisLine)
thisLine = str
}
lastTransformString = sameLineTrans
})
longContextList.push({
...longContext,
})
})
// sort by page number
longContextList = _.sortBy(longContextList, ['page'])
// get sentence list
let sentence = '',
longParagraph = '',
pageList: number[] = [],
flattenSentenceList: {sentence: string, pageList: number[]}[] = [];
_.map(longContextList, longContext => {
const { textlines, page } = longContext || {}
pageList.push(page)
_.map(textlines, (textline, lineIndex) => {
const is_end_index = textline.match(endRegs)?.index || -1
if (is_end_index >= 0) {
// TODO 根据段落来分隔更好
const endSentence = sentence + textline.slice(0, is_end_index + 1)
flattenSentenceList.push({
sentence: endSentence,
pageList: [...pageList],
})
longParagraph += `\n${endSentence}`
sentence = textline.slice(is_end_index + 1)
// pageList 重新计算
// 如果是当页的最后一行,而且句子在此行末尾结束,下一句为新的一页,则不要把当页加入pageList。
pageList = lineIndex + 1 == textlines.length && is_end_index + 1 == textline.length ? [] : [page]
} else {
sentence += textline
}
})
})
// 补上最后一句
if (sentence.length) {
flattenSentenceList.push({
sentence,
pageList: [...pageList],
})
}
console.log(`flattenSentenceList`, flattenSentenceList)
return { longContextList, flattenSentenceList, longParagraph }
}
我们获取到了整个PDF文档的所有文本内容,并且通过 pageCallback 存入当前的状态中供后续使用。这里我们获得了3个字段:
longContextList - 以页面纬度,按照PDF上展示的位置保存每一行的内容
flattenSentenceList - 将整个PDF以句子拆分,并且标记上句子所在的页号,存储成数组
longParagraph - 将所有的整句都拼凑在一起
至此,客户端对PDF文件的处理完毕,之后需要将内容交给服务端坐处理
最后更新于