Maison > développement back-end > C++ > Comment éliminer les espaces blancs lors de la fusion de PDF ?

Comment éliminer les espaces blancs lors de la fusion de PDF ?

Mary-Kate Olsen
Libérer: 2024-12-25 22:43:09
original
414 Les gens l'ont consulté

How to Eliminate White Space When Merging PDFs?

Comment éliminer les espaces lors de la fusion

Question :

J'ai du code qui contient 3 tableaux d'octets PDF différents, et fusionnez-les. Ce code fonctionne bien. Certaines personnes ont des problèmes car chaque PDF est traité comme une page entière (s'il est imprimé), même s'il ne contient qu'environ 4 pouces de contenu, laissant 7 pouces d'espace blanc vertical. Ensuite, le document du milieu est inséré et ne peut comporter aucun espace vertical à la fin. Le pied de page est alors également placé sur sa propre page.

Voici le code :

byte[] Bytes = rv.LocalReport.Render("PDF", null, out MimeType, out Encoding, out Extension, out StreamIDs, out Warnings);
List<byte[]> MergeSets = // 在此代码之前填充

// 将任何其他页面附加到此主要信件
if (MergeSets.Count > 0)
{
    MemoryStream ms = new MemoryStream();
    Document document = new Document();
    PdfCopy copy = new PdfCopy(document, ms);
    document.Open();
    PdfImportedPage page;
    PdfReader reader = new PdfReader(Bytes); // 读取生成的正文信
    int pages = reader.NumberOfPages;

    for (int i = 0; i < pages;)
    {
        page = copy.GetImportedPage(reader, ++i);
        copy.AddPage(page);
    } // 遍历所有正文信的页面

    // 现在附加合并集
    foreach (byte[] ba in MergeSets)
    {
        reader = new PdfReader(ba);
        pages = reader.NumberOfPages;

        for (int i = 0; i < pages;)
        {
            page = copy.GetImportedPage(reader, ++i);
            copy.AddPage(page);
        } // 遍历当前合并集中的所有页面
    } // 遍历数据集中所有内容

    document.Close();

    ServerSaved = SaveGeneratedLetter(ms.GetBuffer(), DateTime.Now.Year, hl.LetterName, SaveName);
} // 如果有待合并的任何内容
Copier après la connexion

Question :

Y a-t-il un moyen de couper/supprimer/supprimer lorsque je fusionne chaque page verticalement un espace blanc à la fin de chaque PDF pour qu'il apparaisse comme un seul document homogène ?

Mise à jour :

Voici des exemples de fichiers .pdf que j'essaie de fusionner.

Titre, corps, pied de page

Mise à jour 2 : Utilisation de la réponse :

J'ai converti le code de @mkl en C# comme indiqué ci-dessous.

La classe utilitaire :

public class PdfVeryDenseMergeTool
{

    private Rectangle PageSize;
    private float TopMargin;
    private float BottomMargin;
    private float Gap;
    private Document Document = null;
    private PdfWriter Writer = null;
    private float YPosition = 0;

    public PdfVeryDenseMergeTool(Rectangle size, float top, float bottom, float gap)
    {
        this.PageSize = size;
        this.TopMargin = top;
        this.BottomMargin = bottom;
        this.Gap = gap;
    } // PdfVeryDenseMergeTool

    public void Merge(MemoryStream outputStream, List<PdfReader> inputs)
    {
        try
        {
            this.OpenDocument(outputStream);

            foreach (PdfReader reader in inputs)
            {
                this.Merge(reader);
            } // 遍历待合并的 PDF 文件
        }
        finally
        {
            this.CloseDocument();
        } // try-catch-finally
    } // Merge

    public void OpenDocument(MemoryStream outputStream)
    {
        this.Document = new Document(PageSize, 36, 36, this.TopMargin, this.BottomMargin);
        this.Writer = PdfWriter.GetInstance(Document, outputStream);

        this.Document.Open();
        this.NewPage();
    } // OpenDocument

    public void CloseDocument()
    {
        try
        {
            this.Document.Close();
        }
        finally
        {
            this.Document = null;
            this.Writer = null;
            this.YPosition = 0;
        } // try-finally
    } // CloseDocument

    public void NewPage()
    {
        this.Document.NewPage();
        this.YPosition = PageSize.GetTop(this.TopMargin);
    } // Merge

    public void Merge(PdfReader reader)
    {
        PdfReaderContentParser parser = new PdfReaderContentParser(reader);

        for (int pageIndex = 1; pageIndex <= reader.NumberOfPages; pageIndex++)
        {
            this.Merge(reader, parser, pageIndex);
        } // 遍历当前 PDF 的所有页面
    } // Merge

    public void Merge(PdfReader reader, PdfReaderContentParser parser, int pageIndex)
    {
        PdfImportedPage importedPage = Writer.GetImportedPage(reader, pageIndex);
        PdfContentByte directContent = Writer.DirectContent;

        PageVerticalAnalyzer finder = parser.ProcessContent(pageIndex, new PageVerticalAnalyzer());

        if (finder.VerticalFlips.Count < 2)
            return;

        Rectangle pageSizeToImport = reader.GetPageSize(pageIndex);

        int startFlip = finder.VerticalFlips.Count - 1;
        bool first = true;

        while (startFlip > 0)
        {
            if (!first)
                this.NewPage();

            float freeSpace = this.YPosition - PageSize.GetBottom(BottomMargin);
            int endFlip = startFlip + 1;

            while ((endFlip > 1) && (finder.VerticalFlips[startFlip] - finder.VerticalFlips[endFlip - 2] < freeSpace))
                endFlip -= 2;

            if (endFlip < startFlip)
            {
                float height = finder.VerticalFlips[startFlip] - finder.VerticalFlips[endFlip];

                directContent.SaveState();
                directContent.Rectangle(0, this.YPosition - height, pageSizeToImport.Width, height);
                directContent.Clip();
                directContent.NewPath();

                this.Writer.DirectContent.AddTemplate(importedPage, 0, this.YPosition - (finder.VerticalFlips[startFlip] - pageSizeToImport.Bottom));

                directContent.RestoreState();
                this.YPosition -= height + this.Gap;
                startFlip = endFlip - 1;
            }
            else if (!first)
            {
                throw new ArgumentException(string.Format("Page {0} content too large", pageIndex));
            } // if

            first = false;
        } // while
    } // Merge
} // PdfVeryDenseMergeTool
Copier après la connexion

La classe d'écoute de rendu :

Mise à jour 3 : Correction d'une ligne de code fonctionne désormais correctement : Voir les commentaires dans le code

public class PageVerticalAnalyzer : IRenderListener
{

    public PageVerticalAnalyzer()
    { }

    public List<float> VerticalFlips = new List<float>();

    public void AddVerticalUseSection(float from, float to)
    {
        if (to < from)
        {
            float temp = to;
            to = from;
            from = temp;
        }

        int i = 0;
        int j = 0;

        for (i = 0; i < VerticalFlips.Count; i++)
        {
            float flip = VerticalFlips[i];
            if (flip < from)
                continue;

            for (j = i; j < VerticalFlips.Count; j++)
            {
                flip = VerticalFlips[j];
                if (flip < to)
                    continue;
                break;
            }
            break;
        } // 遍历所有垂直翻转

        bool fromOutsideInterval = i % 2 == 0;
        bool toOutsideInterval = j % 2 == 0;

        while (j-- > i)
            VerticalFlips.RemoveAt(j); // 这是存在问题的代码行,只使用了 .Remove(j)
        if (toOutsideInterval)
            VerticalFlips.Insert(i, to);
        if (fromOutsideInterval)
            VerticalFlips.Insert(i, from);
    } // AddVerticalUseSection

    public void BeginTextBlock()
    { /* Do nothing */ }

    public void EndTextBlock()
    { /* Do nothing */ }

    public void RenderImage(ImageRenderInfo renderInfo)
    {
        Matrix ctm = renderInfo.GetImageCTM();
        List<float> YCoords = new List<float>(4) { 0, 0, 0, 0 };

        for (int x = 0; x < 2; x++)
        {
            for (int y = 0; y < 2; y++)
            {
                Vector corner = new Vector(x, y, 1).Cross(ctm);
                YCoords[2 * x + y] = corner[Vector.I2];
            }
        }

        YCoords.Sort();
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal