首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >HTML到PDF动态添加目录(TOC)

HTML到PDF动态添加目录(TOC)
EN

Stack Overflow用户
提问于 2020-02-29 23:16:46
回答 2查看 2.9K关注 0票数 3

我正在使用iText 7将html转换为PDF,但我甚至找不到一个例子来说明如何向最终的PDF添加目录。在遵循iText示例这里时,将文本转换为PDF并添加TOC是一项简单的任务,但很明显,当将HTML转换为PDF时是不可能的。

需求很简单,只需查找所有HTML标记属性"data- TOC“,并使用该值创建TOC。

下面是我到目前为止使用PDF样例这里的文本中使用的相同方法所得到的信息

  • VS 2019年

Program.cs

代码语言:javascript
复制
using System.IO;

namespace ConsoleApp
{
    class Program
    {
        private const string SRC = @"C:\iText\sxsw.html";
        private const string DEST = @"C:\iText\sxsw.pdf";

        static void Main(string[] args)
        {
            FileInfo file = new FileInfo(DEST);

            file.Directory.Create();

            new HtmlAndToc().CreatePdf(SRC, DEST);
        }
    }
}

HtmlAndTOC.cs

代码语言:javascript
复制
using iText.Html2pdf;
using iText.Html2pdf.Attach;
using iText.Html2pdf.Attach.Impl;
using iText.Html2pdf.Resolver.Font;
using iText.Kernel.Pdf;
using iText.StyledXmlParser.Node;
using System;
using System.IO;

namespace ConsoleApp
{
    class HtmlAndToc
    {
        public void CreatePdf(string src, string dest)
        {
            ConverterProperties properties = new ConverterProperties();
            properties.SetFontProvider(new DefaultFontProvider(true, true, true));

            // Custom Factory
            properties.SetTagWorkerFactory(new CustomTagWorkerFactory());

            PdfWriter writer = new PdfWriter(dest);
            PdfDocument pdfDoc = new PdfDocument(writer);
            pdfDoc.SetTagged();

            FileStream htmlStream = new FileStream(src, FileMode.Open);

            HtmlConverter.ConvertToPdf(htmlStream, pdfDoc, properties);

            htmlStream.Close();
            pdfDoc.Close();
        }
    }

    public class CustomTagWorkerFactory : DefaultTagWorkerFactory
    {
        public override ITagWorker GetCustomTagWorker(IElementNode tag, ProcessorContext context)
        {
            string dataTocAttrValue = tag.GetAttribute("data-toc");

            if (String.IsNullOrWhiteSpace(dataTocAttrValue))
            {
                return null;
            }

            // At this point I have the HTML element and the data-toc attribute value that is a TOC title to be associated to a page number
            // Because the data-toc attribute can be on any HTML element type I couldn't find a way to create an Outline/AddDestination nor 
            // a way to SetNextRenderer to keep the page number updated as the Text to PDF example does in
            // https://itextpdf.com/en/resources/examples/itext-7/toc-first-page

            Console.WriteLine(dataTocAttrValue);

            return null;
        }
    }
}

这里有一个示例HTML文件:

代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head>
    <!-- example from:  https://itextpdf.com/  -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" type="text/css" href="css/sxsw.css"/>
	<link rel="stylesheet" media="print only" href="css/sxsw_print.css">
    <!-- Based on the reponsive design example found at https://www.w3schools.com/css/css_rwd_intro.asp -->
</head>
<body>
<div class="header">
    <h1>SXSW</h1>
</div>
<div class="container">
    <div class="one col-1-m col-1 menu">
        <ul data-toc="Activities">
            <li>Interactive</li>
            <li>Film</li>
            <li>Music</li>
            <li>Comedy</li>
        </ul>
    </div>
    <div class="two col-3-m col-3 ">
        <h1>South by Southwest</h1>
        <p>The South by Southwest&reg; (SXSW&reg;) Conference &amp; Festivals in Austin (TX) celebrate
		the convergence of the interactive, film, and music industries.
		Fostering creative and professional growth alike, SXSW&reg; is the premier destination for discovery.</p>
    </div>
    <div class="three col-4-m col-1">
        <div data-toc="South by Southwest Conference" class="aside">
            <h2>Conference</h2>
            <p>The SXSW conference is an amazing conglomeration of people, places, brands, music, tech and film.</p>
            <h2>Festivals</h2>
            <p>The different SXSW festivals take place for 10 days in mid-March Every year,
            with SXSW Interactive lasting for 5 days, Music for 6 days, and Film &amp; Comedy running concurrently for 9 days.</p>
            <p>
                The SXSW Conference features 25 different tracks that prove the most unexpected discoveries happen when diverse topics and people come together.
                In 2017, SXSW equipped 421,900 people from 95 countries. There were 2,887 sessions by 5,280 speakers for 70,969 attendees.
                In addition to its conference, SXSW is known for its four festivals: interactive, film, music, and comedy.
            </p>
            <p>
                The evening networking events that make up the SXSW Interactive Festival range from parties, award presentations, private events, and more.
                In 2017, there were 1,084 official parties and events.
            </p>
            <p>
                The SXSW Film Festival has become known for the high caliber and diversity of films presented, and for its smart, enthusiastic audiences.
                Running the length of SXSWeek, Film festival attendees can connect with tech and music industry experts for an unparalleled experience at the forefront of discovery, creativity, and innovation.
                SXSW 2017 brought 171 Shorts, 130 Features, of which 83 World Premieres for 70,547 Attendees.
            </p>
            <p>
                The SXSW Music Festival is the most influential music industry event in the world.
                Record labels, booking agencies, management and PR firms, export offices, publishers, media outlets,
                tastemakers, and lifestyle brands converge to see thousands of artists perform in venues all throughout downtown Austin.
                In 2017, there were 167,800 attendees for 2,085 Performing Acts, of which 544 International acts from 63 different countries.
            </p>
            <p>
                The SXSW Conference features 25 different tracks that prove the most unexpected discoveries happen when diverse topics and people come together.
                In 2017, SXSW equipped 421,900 people from 95 countries. There were 2,887 sessions by 5,280 speakers for 70,969 attendees.
                In addition to its conference, SXSW is known for its four festivals: interactive, film, music, and comedy.
            </p>
            <p>
                The evening networking events that make up the SXSW Interactive Festival range from parties, award presentations, private events, and more.
                In 2017, there were 1,084 official parties and events.
            </p>
            <p>
                The SXSW Film Festival has become known for the high caliber and diversity of films presented, and for its smart, enthusiastic audiences.
                Running the length of SXSWeek, Film festival attendees can connect with tech and music industry experts for an unparalleled experience at the forefront of discovery, creativity, and innovation.
                SXSW 2017 brought 171 Shorts, 130 Features, of which 83 World Premieres for 70,547 Attendees.
            </p>
            <p>
                The SXSW Music Festival is the most influential music industry event in the world.
                Record labels, booking agencies, management and PR firms, export offices, publishers, media outlets,
                tastemakers, and lifestyle brands converge to see thousands of artists perform in venues all throughout downtown Austin.
                In 2017, there were 167,800 attendees for 2,085 Performing Acts, of which 544 International acts from 63 different countries.
            </p>
            <h2>Exhibitions</h2>
            <p>Trade Show, Flatstock, SXSW Marketplace, Job Market, SXSW Create, Gaming Expo, Southbites Trailer Park, Spotlights.</p>
            <p>
                The SXSW Conference features 25 different tracks that prove the most unexpected discoveries happen when diverse topics and people come together.
                In 2017, SXSW equipped 421,900 people from 95 countries. There were 2,887 sessions by 5,280 speakers for 70,969 attendees.
                In addition to its conference, SXSW is known for its four festivals: interactive, film, music, and comedy.
            </p>
            <p>
                The evening networking events that make up the SXSW Interactive Festival range from parties, award presentations, private events, and more.
                In 2017, there were 1,084 official parties and events.
            </p>
            <p>
                The SXSW Film Festival has become known for the high caliber and diversity of films presented, and for its smart, enthusiastic audiences.
                Running the length of SXSWeek, Film festival attendees can connect with tech and music industry experts for an unparalleled experience at the forefront of discovery, creativity, and innovation.
                SXSW 2017 brought 171 Shorts, 130 Features, of which 83 World Premieres for 70,547 Attendees.
            </p>
            <p>
                The SXSW Music Festival is the most influential music industry event in the world.
                Record labels, booking agencies, management and PR firms, export offices, publishers, media outlets,
                tastemakers, and lifestyle brands converge to see thousands of artists perform in venues all throughout downtown Austin.
                In 2017, there were 167,800 attendees for 2,085 Performing Acts, of which 544 International acts from 63 different countries.
            </p>
            <p>
                The SXSW Conference features 25 different tracks that prove the most unexpected discoveries happen when diverse topics and people come together.
                In 2017, SXSW equipped 421,900 people from 95 countries. There were 2,887 sessions by 5,280 speakers for 70,969 attendees.
                In addition to its conference, SXSW is known for its four festivals: interactive, film, music, and comedy.
            </p>
            <p>
                The evening networking events that make up the SXSW Interactive Festival range from parties, award presentations, private events, and more.
                In 2017, there were 1,084 official parties and events.
            </p>
            <p>
                The SXSW Film Festival has become known for the high caliber and diversity of films presented, and for its smart, enthusiastic audiences.
                Running the length of SXSWeek, Film festival attendees can connect with tech and music industry experts for an unparalleled experience at the forefront of discovery, creativity, and innovation.
                SXSW 2017 brought 171 Shorts, 130 Features, of which 83 World Premieres for 70,547 Attendees.
            </p>
            <p>
                The SXSW Music Festival is the most influential music industry event in the world.
                Record labels, booking agencies, management and PR firms, export offices, publishers, media outlets,
                tastemakers, and lifestyle brands converge to see thousands of artists perform in venues all throughout downtown Austin.
                In 2017, there were 167,800 attendees for 2,085 Performing Acts, of which 544 International acts from 63 different countries.
            </p>
        </div>
    </div>
</div>
<div class="container">
    <h2 class="header">SXSW Conference and festivals</h2>
    <p data-toc="SXSW Conference and festivals">
        The SXSW Conference features 25 different tracks that prove the most unexpected discoveries happen when diverse topics and people come together.
		In 2017, SXSW equipped 421,900 people from 95 countries. There were 2,887 sessions by 5,280 speakers for 70,969 attendees.
		In addition to its conference, SXSW is known for its four festivals: interactive, film, music, and comedy.
    </p>
	<p>
		The evening networking events that make up the SXSW Interactive Festival range from parties, award presentations, private events, and more.
		In 2017, there were 1,084 official parties and events.
	</p>
    <p>
        The SXSW Film Festival has become known for the high caliber and diversity of films presented, and for its smart, enthusiastic audiences.
		Running the length of SXSWeek, Film festival attendees can connect with tech and music industry experts for an unparalleled experience at the forefront of discovery, creativity, and innovation.
		SXSW 2017 brought 171 Shorts, 130 Features, of which 83 World Premieres for 70,547 Attendees.
    </p>
    <p>
        The SXSW Music Festival is the most influential music industry event in the world.
		Record labels, booking agencies, management and PR firms, export offices, publishers, media outlets,
		tastemakers, and lifestyle brands converge to see thousands of artists perform in venues all throughout downtown Austin.
		In 2017, there were 167,800 attendees for 2,085 Performing Acts, of which 544 International acts from 63 different countries.
    </p>
    <p>
        Growing from a singular night's celebration of comedy's biggest names into a week-long whirlwind of a festival,
		the SXSW Comedy Festival presents uniquely diverse programming that highlights exceptional emerging and established talent.
    </p>
    <p>
        The SXSW Conference features 25 different tracks that prove the most unexpected discoveries happen when diverse topics and people come together.
		In 2017, SXSW equipped 421,900 people from 95 countries. There were 2,887 sessions by 5,280 speakers for 70,969 attendees.
		In addition to its conference, SXSW is known for its four festivals: interactive, film, music, and comedy.
    </p>
	<p>
		The evening networking events that make up the SXSW Interactive Festival range from parties, award presentations, private events, and more.
		In 2017, there were 1,084 official parties and events.
	</p>
    <p>
        The SXSW Film Festival has become known for the high caliber and diversity of films presented, and for its smart, enthusiastic audiences.
		Running the length of SXSWeek, Film festival attendees can connect with tech and music industry experts for an unparalleled experience at the forefront of discovery, creativity, and innovation.
		SXSW 2017 brought 171 Shorts, 130 Features, of which 83 World Premieres for 70,547 Attendees.
    </p>
    <p>
        The SXSW Music Festival is the most influential music industry event in the world.
		Record labels, booking agencies, management and PR firms, export offices, publishers, media outlets,
		tastemakers, and lifestyle brands converge to see thousands of artists perform in venues all throughout downtown Austin.
		In 2017, there were 167,800 attendees for 2,085 Performing Acts, of which 544 International acts from 63 different countries.
    </p>
    <p>
        Growing from a singular night's celebration of comedy's biggest names into a week-long whirlwind of a festival,
		the SXSW Comedy Festival presents uniquely diverse programming that highlights exceptional emerging and established talent.
    </p>
    <p>
        The SXSW Conference features 25 different tracks that prove the most unexpected discoveries happen when diverse topics and people come together.
		In 2017, SXSW equipped 421,900 people from 95 countries. There were 2,887 sessions by 5,280 speakers for 70,969 attendees.
		In addition to its conference, SXSW is known for its four festivals: interactive, film, music, and comedy.
    </p>
	<p>
		The evening networking events that make up the SXSW Interactive Festival range from parties, award presentations, private events, and more.
		In 2017, there were 1,084 official parties and events.
	</p>
    <p>
        The SXSW Film Festival has become known for the high caliber and diversity of films presented, and for its smart, enthusiastic audiences.
		Running the length of SXSWeek, Film festival attendees can connect with tech and music industry experts for an unparalleled experience at the forefront of discovery, creativity, and innovation.
		SXSW 2017 brought 171 Shorts, 130 Features, of which 83 World Premieres for 70,547 Attendees.
    </p>
    <p>
        The SXSW Music Festival is the most influential music industry event in the world.
		Record labels, booking agencies, management and PR firms, export offices, publishers, media outlets,
		tastemakers, and lifestyle brands converge to see thousands of artists perform in venues all throughout downtown Austin.
		In 2017, there were 167,800 attendees for 2,085 Performing Acts, of which 544 International acts from 63 different countries.
    </p>
    <p>
        Growing from a singular night's celebration of comedy's biggest names into a week-long whirlwind of a festival,
		the SXSW Comedy Festival presents uniquely diverse programming that highlights exceptional emerging and established talent.
    </p>
    <p>
        The SXSW Conference features 25 different tracks that prove the most unexpected discoveries happen when diverse topics and people come together.
		In 2017, SXSW equipped 421,900 people from 95 countries. There were 2,887 sessions by 5,280 speakers for 70,969 attendees.
		In addition to its conference, SXSW is known for its four festivals: interactive, film, music, and comedy.
    </p>
	<p>
		The evening networking events that make up the SXSW Interactive Festival range from parties, award presentations, private events, and more.
		In 2017, there were 1,084 official parties and events.
	</p>
    <p>
        The SXSW Film Festival has become known for the high caliber and diversity of films presented, and for its smart, enthusiastic audiences.
		Running the length of SXSWeek, Film festival attendees can connect with tech and music industry experts for an unparalleled experience at the forefront of discovery, creativity, and innovation.
		SXSW 2017 brought 171 Shorts, 130 Features, of which 83 World Premieres for 70,547 Attendees.
    </p>
    <p>
        The SXSW Music Festival is the most influential music industry event in the world.
		Record labels, booking agencies, management and PR firms, export offices, publishers, media outlets,
		tastemakers, and lifestyle brands converge to see thousands of artists perform in venues all throughout downtown Austin.
		In 2017, there were 167,800 attendees for 2,085 Performing Acts, of which 544 International acts from 63 different countries.
    </p>
    <p>
        Growing from a singular night's celebration of comedy's biggest names into a week-long whirlwind of a festival,
		the SXSW Comedy Festival presents uniquely diverse programming that highlights exceptional emerging and established talent.
    </p>
    <h2 class="header">Exhibitions</h2>
    <div class="container">
        <div class="col-2-m col-3">
            <div><span data-toc="Exhibitions One" class=exhibition>SXSW Trade Show:</span>
			The all-encompassing exhibition for creative industries.</div>
            <div><span data-toc="Exhibitions Two" class=exhibition>Flatstock:</span>
			The world's top gig posters and artists.</div>
            <div><span data-toc="Exhibitions Three" class=exhibition>SXSW Marketplace:</span>
			One big pop-up shop at the center of SXSW.</div>
            <div><span class=exhibition>Job Market:</span>
			Where innovative talent and companies connect.</div>
        </div>
        <div class="col-2-m col-3">
            <div><span data-toc="Exhibitions Four" class=exhibition>SXSW Create:</span>
			Hands on creative fun for imaginations of all ages.</div>
            <div><span data-toc="Exhibitions Six"class=exhibition>Gaming Expo:</span>
			The hub of gaming culture at SXSW.</div>
            <div><span class=exhibition>Southbites Trailer Park:</span>
			Featuring some of the best food trucks around.</div>
            <div><span class=exhibition>Spotlights:</span>
			Highlighting one-one-one connections with promising startups.</div>
        </div>
    </div>
</div>
</body>
</html>

我希望这是一个很好的问题,谢谢你的帮助。

EN

回答 2

Stack Overflow用户

发布于 2021-02-07 12:20:51

我的答案是使用Java,但您可以轻松地将其转换为.NET,因为我将要使用的Jsoup版本是嵌入到iText中的,而转换的其余部分基本上是从大写字母开始更改方法名称。

现在可以用纯pdfHTML 3.0.3+生成一个目录,但这自然需要对您的HTML文件进行一些预处理。

其思想是,我们将循环使用data-toc标记的元素,并创建相应的内容表元素。最有趣的部分是生成页码,这些页码表示我们所引用的内容放置的页面。我们将为此使用target-counter CSS函数,我们还将使用data-toc属性标记所有元素,以便能够在target-counter上下文中引用它们,并在纯链接中跳转到这些元素。

下面是一个包含一些助手注释的示例代码:

代码语言:javascript
复制
Document htmlDoc = Jsoup.parse(new File("path/to/in.html"), "UTF-8");

// This is our Table of Contents aggregating element
Element tocElement = htmlDoc.body().prependElement("div");
tocElement.append("<b>Table of contents</b>");

// We are going to build a complex CSS
StringBuilder tocStyles = new StringBuilder().append("<style>");

Elements tocElements = htmlDoc.select("[data-toc]");
for (Element elem : tocElements) {
    // Here we create an anchor to be able to refer to this element when generating page numbers and links
    String id = UUID.randomUUID().toString();
    elem.attr("id", id);

    // CSS selector to show page numebr for a TOC entry
    tocStyles.append("*[data-toc-id=\"" + id + "\"] .toc-page-ref::after { content: target-counter(#" + id + ", page) }");

    // Generating TOC entry as a small table to align page numbers on the right
    Element tocEntry = tocElement.appendElement("table");
    tocEntry.attr("style", "width: 100%");
    Element tocEntryRow = tocEntry.appendElement("tr");
    tocEntryRow.attr("data-toc-id", id);
    Element tocEntryTitle = tocEntryRow.appendElement("td");
    tocEntryTitle.appendText(elem.attr("data-toc"));
    Element tocEntryPageRef = tocEntryRow.appendElement("td");
    tocEntryPageRef.attr("style", "text-align: right");
    // <span> is a placeholder element where target page number will be inserted
    // It is wrapped by an <a> tag to create links pointing to the element in our document
    tocEntryPageRef.append("<a href=\"#" + id + "\"><span class=\"toc-page-ref\"></span></a>");
}


tocStyles.append("</style>");

htmlDoc.head().append(tocStyles.toString());

String html = htmlDoc.outerHtml();

HtmlConverter.convertToPdf(html, new FileOutputStream("path/to/out.pdf"));

使用上述代码和示例文件对结果进行可视化表示:

票数 2
EN

Stack Overflow用户

发布于 2021-05-07 15:32:23

我的回答基本上和亚历克西的一样,只是我会尽量简化一下。

其中大部分将使用目标计数器的文档,位于这里:https://www.oxygenxml.com/doc/versions/23.1/ug-editor/topics/dg-target-counter-function.html

遵循这个基本结构。在文档正文中,向要链接的任何内容添加一个id。在目录中,为每个id添加一个href:

代码语言:javascript
复制
<html>
  <body>

    <div class="toc-container">
      <div class="toc-row"><a href="#one">Link To Page One</a></div>
      <div class="toc-row"><a href="#two">Link To Page Two</a></div>
    </div>

    <div class="content-container">
      <div class="page" id="one">Page One Content Here</div>
      <div class="page" id="two">Page Two Content Here</div>
    </div>

  </body>
</html>

那么,实现目录的css非常简单:

代码语言:javascript
复制
.toc-row a::after {
  content: leader('.') target-counter(attr(href), page, decimal);
}

就这样。目标计数器使用href获取页码,并将该页码放在目录中。您可以随意设计它的样式,但是基本的样式最终看起来如下所示:

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60470539

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档