我有幾個大的 PDF 檔案(70-200,每頁)。PDF 本身是從 HTML 頁面生成的(我無法獲得 HTML 頁面的源代碼,這就是我使用 PDF 的原因)。無論如何,我想做的是根據轉換后的 H1 標簽屬性將 PDF 決議為單獨的頁面。當我列印出 PDF 時,我得到了這個:
Seller Tag (AST)
{
NSBaselineOffset = 0;
NSColor = "Device RGB colorspace 0.94118 0.32549 0.29804 1";
NSFont = "\"Helvetica 8.00 pt. P [] (0x7ff0f262e590) fobj=0x7ff0f4339680, spc=2.22\"";
}Table of Contents
{
NSBaselineOffset = 0;
NSColor = "Device RGB colorspace 0.94118 0.32549 0.29804 1";
NSFont = "\"Helvetica 34.00 pt. P [] (0x7ff0f262e590) fobj=0x7ff0f432f940, spc=9.45\"";
}...
它看起來像包含在字典中的一堆屬性。但是當我運行這段代碼時:
let strContent = myAppManager.pdfToText(fromPDF:pdfDirPath.absoluteString "/" thisFile)
let strPDF:NSAttributedString = strContent
let strNSPDF = strPDF.string as NSString
let rangeOfString = NSMakeRange(0, strNSPDF.length)
let arrAttributes = strPDF.attributes(at: 0, longestEffectiveRange: nil, in: rangeOfString)
print(arrAttributes)
我得到這個輸出
[__C.NSAttributedStringKey(_rawValue: NSColor): Device RGB colorspace 0.94118 0.32549 0.29804 1, __C.NSAttributedStringKey(_rawValue: NSBaselineOffset): 0, __C.NSAttributedStringKey(_rawValue: NSFont): "Helvetica 8.00 pt. P [] (0x7ff0f441d490) fobj=0x7ff0f4339680, spc=2.22"]
我有點期待一個很高的數字,比如 1000 個或更多的條目,而不是 1。
所以窺探一下,我知道 H1 HTML 標簽被轉換成這樣:
Table of Contents
{
NSBaselineOffset = 0;
NSColor = "Device RGB colorspace 0.94118 0.32549 0.29804 1";
NSFont = "\"Helvetica 34.00 pt. P [] (0x7ff0f262e590) fobj=0x7ff0f432f940, spc=9.45\"";
}
所以我想要做的是分隔轉換后的 H1,這樣我就可以將內容作為一個頁面來獲取并用它做一些事情。任何想法或建議將不勝感激。
uj5u.com熱心網友回復:
快速完成,假設您有:
someText[HEADER1]someText1[HEADER2]someText2[HEADER3]someText3...
Where[HEADERN]具有相同的屬性(并且您知道它們)但與someTextN.
我們要到底,和陣列:
struct Page: CustomStringConvertible {
let title: NSAttributedString? //Tha's be the h1 tag content
let content: NSAttributedString?
var description: String {
return "Title: \(title?.string ?? "") - content: \(content?.string ?? "")"
}
}
初始樣本:
let htmlString = "<b>Title 1</b> Text for part one.\n <b>Title 2</b> Text for part two<b>Title 3</b>Text for part three"
let attributedString = try! NSAttributedString(data: Data(htmlString.utf8),
options: [.documentType : NSAttributedString.DocumentType.html],
documentAttributes: nil)
和:
let headerAttributes: [NSAttributedString.Key: Any] = [.font: UIFont.boldSystemFont(ofSize: 12)]
print("headerAttributes: \(headerAttributes)")
func headerOneAttributes(_ headerAttributes: [NSAttributedString.Key: Any], matches attributes: [NSAttributedString.Key: Any]?) -> Bool {
guard let attributes = attributes else { return false }
guard let attributesFont = attributes[.font] as? NSFont, let headerFont = headerAttributes[.font] as? NSFont else {
return false
}
return attributesFont.fontDescriptor.symbolicTraits == NSFontDescriptor.SymbolicTraits(rawValue: 268435458) //Here fonts arent' equal equal, some work here plus checking on other attributes too and font size?
// Do you own check
// return false
}
我們可以迭代屬性以獲取所有標題范圍:
var headerRanges: [NSRange] = []
attributedString.enumerateAttributes(in: NSRange(location: 0, length: attributedString.length), options: []) { attributes, range, stop in
if headerOneAttributes(headerAttributes, matches: attributes) {
headerRanges.append(range)
}
}
對范圍進行迭代:
var pages: [Page] = []
guard !headerRanges.isEmpty else { return }
//In case the first title doesn't "start at the beginning", we have a "content" with no title at start
if let first = headerRanges.first, first.location > 0 {
pages.append(Page(title: nil, content: attributedString.attributedSubstring(from: first)))
}
// Then we iterate
for (anIndex, aRange) in headerRanges.enumerated() {
print(pages)
let title = attributedString.attributedSubstring(from: aRange)
let subtext: NSAttributedString?
// If there is a "nextRange", then we get the end of subtext from it
if anIndex 1 <= headerRanges.count - 1 {
let next = headerRanges[anIndex 1]
let location = aRange.location aRange.length
let length = next.location - location
subtext = attributedString.attributedSubstring(from: NSRange(location: location, length: length))
} else {
//There is no next => Until the end
let location = aRange.location aRange.length
let length = attributedString.length - location
subtext = attributedString.attributedSubstring(from: NSRange(location: location, length: length))
}
pages.append(Page(title:title, content: subtext))
}
print(pages)
PS:UIFont/NSFont:~相同,我在 macOS 應用程式上測驗,而不是 iOS,這就是原因。
uj5u.com熱心網友回復:
好的,所以@Larme 讓我走上了我正在尋找的正確軌道。發布代碼希望它可以幫助其他人。我已經在一個 77 頁的檔案上測驗過它并且它起作用了。我應該在問題中指出我正在使用 MacOS。
func parsePDF(_ strPDFContent:NSMutableAttributedString) -> Array<Dictionary<String, Any>> {
//some initial setup
let strNSPDF = strPDFContent.string as NSString
var arrDocSet:Array<Dictionary<String, Any>> = []
//get all the page headers
var arrRanges = [NSRange]()
strPDFContent.enumerateAttribute(NSAttributedString.Key.font, in: NSRange(0..<strPDFContent.length), options: .longestEffectiveRangeNotRequired) {
value, range, stop in
if let thisFont = value as? NSFont {
if thisFont.pointSize == 34 {
arrRanges.append(range)
}
}
}
//get the content and store data
for (idx, range) in arrRanges.enumerated() {
//get title
let strTitle = String(strNSPDF.substring(with: range))
var textRange = NSRange(location:0, length:0)
//skip opening junk
if !strTitle.contains("Table of Contents\n") {
if idx < arrRanges.count-1 {
textRange = NSRange(location: range.upperBound, length: arrRanges[idx 1].lowerBound - range.upperBound)
} else if idx == arrRanges.count-1 {
textRange = NSRange(location: range.upperBound, length: strNSPDF.length - range.upperBound)
}
let strContent = String(strNSPDF.substring(with: textRange))
arrDocSet.append(["title":strTitle, "content":strContent, "contentRange":textRange, "titleRange":range])
}
}
print(arrDocSet)
return arrDocSet
}
這將輸出:
["titleRange": {10001, 27}, "title": "Set up Placements with AST\n", "content": "This page contains a sample web page showing how Xandr\'s seller tag (AST) functions can be implemented in the header and body of a sample client page.\nSee AST API Reference for more details on using ...
...
ready.\nExample\n$sf.ext.status();\n", "title": " SafeFrame API Reference\n", "contentRange": {16930, 9841}
讓我知道是否有可以提高效率的地方。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/323940.html
